diff --git a/default.nix b/default.nix index 202a106..43df690 100644 --- a/default.nix +++ b/default.nix @@ -1,5 +1,5 @@ -{buildGoModule}: -buildGoModule { +{buildGoLatestModule}: +buildGoLatestModule { pname = "tsnet-proxy"; version = "0.1"; pwd = ./.; diff --git a/flake.lock b/flake.lock index 42ea3b1..886d2d9 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1771369470, - "narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=", + "lastModified": 1792502884, + "narHash": "sha256-IoNisKcGbUjdd45qCqywGMCYmZ5EnkxezvLII0FWwNA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0182a361324364ae3f436a63005877674cf45efb", + "rev": "02c087f3fe673c9e317f206a627cb6b910336dbe", "type": "github" }, "original": { diff --git a/go.mod b/go.mod index 7556996..fb56a5c 100644 --- a/go.mod +++ b/go.mod @@ -1,66 +1,66 @@ module ben.soroos.net/tsnet-proxy -go 1.25.5 +go 1.27.3 -require tailscale.com v1.94.1 +require tailscale.com v1.104.1 require ( - filippo.io/edwards25519 v1.1.0 // indirect + filippo.io/edwards25519 v1.2.0 // indirect github.com/akutz/memconn v0.1.0 // indirect - github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect - github.com/aws/aws-sdk-go-v2 v1.41.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.29.5 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.58 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 // indirect + github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e // indirect + github.com/aws/aws-sdk-go-v2 v1.46.0 // indirect + github.com/aws/aws-sdk-go-v2/config v1.33.3 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.20.3 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.19.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.2 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 // indirect - github.com/aws/smithy-go v1.24.0 // indirect - github.com/coder/websocket v1.8.12 // indirect - github.com/creachadair/msync v0.7.1 // indirect - github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect - github.com/gaissmai/bart v0.18.0 // indirect - github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced // indirect - github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.37.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.42.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.49.0 // indirect + github.com/aws/smithy-go v1.28.1 // indirect + github.com/coder/websocket v1.8.15 // indirect + github.com/creachadair/msync v0.10.1 // indirect + github.com/dblohm7/wingoes v0.0.0-20260526185140-fb298caac7ca // indirect + github.com/fxamacker/cbor/v2 v2.9.3 // indirect + github.com/gaissmai/bart v0.29.0 // indirect + github.com/go-json-experiment/json v0.0.0-20260820222146-c27c302e5fc3 // indirect + github.com/godbus/dbus/v5 v5.2.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hdevalence/ed25519consensus v0.2.0 // indirect github.com/huin/goupnp v1.3.0 // indirect - github.com/jsimonetti/rtnetlink v1.4.0 // indirect - github.com/klauspost/compress v1.18.2 // indirect - github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 // indirect - github.com/mdlayher/socket v0.5.0 // indirect + github.com/jsimonetti/rtnetlink v1.4.2 // indirect + github.com/klauspost/compress v1.20.0 // indirect + github.com/mdlayher/netlink v1.11.2 // indirect + github.com/mdlayher/socket v0.7.0 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect - github.com/pires/go-proxyproto v0.8.1 // indirect + github.com/pires/go-proxyproto v0.15.0 // indirect github.com/prometheus-community/pro-bing v0.4.0 // indirect - github.com/safchain/ethtool v0.3.0 // indirect - github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e // indirect + github.com/safchain/ethtool v0.7.0 // indirect + github.com/tailscale/certstore v0.1.1-0.20260409135935-3638fb84b77d // indirect github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect - github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a // indirect + github.com/tailscale/hujson v0.0.0-20260727124030-b80ff77dac4f // indirect github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc // indirect - github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 // indirect - github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da // indirect + github.com/tailscale/web-client-prebuilt v0.0.0-20260917222731-e0ed2d0d0fea // indirect + github.com/tailscale/wireguard-go v0.0.0-20260928213032-417aef361226 // indirect github.com/x448/float16 v0.8.4 // indirect go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect - go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.46.0 // indirect - golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/oauth2 v0.32.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/term v0.38.0 // indirect - golang.org/x/text v0.32.0 // indirect - golang.org/x/time v0.12.0 // indirect + go4.org/netipx v0.0.0-20260823151212-3075585bcbeb // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba // indirect + golang.org/x/net v0.59.0 // indirect + golang.org/x/oauth2 v0.37.0 // indirect + golang.org/x/sync v0.23.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/term v0.46.0 // indirect + golang.org/x/text v0.42.0 // indirect + golang.org/x/time v0.16.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect - golang.zx2c4.com/wireguard/windows v0.5.3 // indirect - gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 // indirect + golang.zx2c4.com/wireguard/windows v1.0.1 // indirect + gvisor.dev/gvisor v0.0.0-20260915211658-a6f909f08a72 // indirect ) diff --git a/go.sum b/go.sum index 135345d..67c0444 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ 9fans.net/go v0.0.8-0.20250307142834-96bdba94b63f/go.mod h1:hHyrZRryGqVdqrknjq5OWDLGCTJ2NeEvtrpR96mjraM= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= +filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= filippo.io/mkcert v1.4.4 h1:8eVbbwfVlaqUM7OwuftKc2nuYOoTDQWqsoXmzoXZdbc= filippo.io/mkcert v1.4.4/go.mod h1:VyvOchVuAye3BoUsPUOOofKygVwLV2KQMVFJNRq+1dA= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= @@ -10,52 +12,72 @@ github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4= github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0= +github.com/aws/aws-sdk-go-v2 v1.46.0/go.mod h1:bttEH6JqnUL8LepvDVfdrds/fZ5bCIxzpe3abyUrhDU= github.com/aws/aws-sdk-go-v2/config v1.29.5 h1:4lS2IB+wwkj5J43Tq/AwvnscBerBJtQQ6YS7puzCI1k= github.com/aws/aws-sdk-go-v2/config v1.29.5/go.mod h1:SNzldMlDVbN6nWxM7XsUiNXPSa1LWlqiXtvh/1PrJGg= +github.com/aws/aws-sdk-go-v2/config v1.33.3/go.mod h1:YYDB1kTejxbfAbEVUqgCtkVp26xvNCHev9cLKABMGAk= github.com/aws/aws-sdk-go-v2/credentials v1.17.58 h1:/d7FUpAPU8Lf2KUdjniQvfNdlMID0Sd9pS23FJ3SS9Y= github.com/aws/aws-sdk-go-v2/credentials v1.17.58/go.mod h1:aVYW33Ow10CyMQGFgC0ptMRIqJWvJ4nxZb0sUiuQT/A= +github.com/aws/aws-sdk-go-v2/credentials v1.20.3/go.mod h1:wfGneWyncO7p67wqXV2IQhPk14JqIc25woKlaArT3WI= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 h1:7lOW8NUwE9UZekS1DYoiPdVAqZ6A+LheHWb+mHbNOq8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27/go.mod h1:w1BASFIPOPUae7AgaH4SbjNbfdkxuggLyGfNFTn8ITY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.19.2/go.mod h1:XyK6UV8xbo66ysVqLd2783C09pBYHOm8aKTRV5DVJ30= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 h1:rgGwPzb82iBYSvHMHXc8h9mRoOUBZIGFgKb9qniaZZc= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16/go.mod h1:L/UxsGeKpGoIj6DxfhOWHWQ/kGKcd4I1VncE4++IyKA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.5.2/go.mod h1:TD1jvU2LvXkJexct5vBqcd8QlNXh5EmRUeL/Z32p0n4= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 h1:1jtGzuV7c82xnqOVfx2F0xmJcOw5374L7N6juGW6x6U= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16/go.mod h1:M2E5OQf+XLe+SZGmmpaI2yy+J326aFf6/+54PoxSANc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.8.2/go.mod h1:63HDfhFkdzBpI8WGXTSKUHPKS6mqldj4u3LJW7RZtSU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.19/go.mod h1:KaUzbLxv4CeSxh6ZCl9B4m7CuFenS8kUEaDs+f/DQr4= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.14.2/go.mod h1:a1NXrYpBd311gBzn1UI5UzJyyvXktM4xNh/ydPiPpqY= github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7 h1:a8HvP/+ew3tKwSXqL3BCSjiuicr+XTU2eFYeogV9GJE= github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7/go.mod h1:Q7XIWsMo0JcMpI/6TGD6XXcXcV1DbTj6e9BKNntIMIM= github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 h1:c5WJ3iHz7rLIgArznb3JCSQT3uUMiz9DLZhIX+1G8ok= github.com/aws/aws-sdk-go-v2/service/sso v1.24.14/go.mod h1:+JJQTxB6N4niArC14YNtxcQtwEqzS3o9Z32n7q33Rfs= +github.com/aws/aws-sdk-go-v2/service/sso v1.37.0/go.mod h1:XFlVwUsw3sYh8Hw37umYVJnrcWrwXWRxbNw/JY0bblw= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 h1:f1L/JtUkVODD+k1+IiSJUUv8A++2qVr+Xvb3xWXETMU= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13/go.mod h1:tvqlFoja8/s0o+UruA1Nrezo/df0PzdunMDDurUfg6U= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.42.0/go.mod h1:588e7skMkYIYkSUseT8E3WKFfbAfrA1bj3Zf+qxJtJY= github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX1s+lFTg4+4DOy70= github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk= +github.com/aws/aws-sdk-go-v2/service/sts v1.49.0/go.mod h1:zMBwjSf4Pt8a1OHYiZ5rPD0PJRK1kQrUaxhS/Dbld8E= github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk= github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +github.com/aws/smithy-go v1.28.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/axiomhq/hyperloglog v0.0.0-20240319100328-84253e514e02 h1:bXAPYSbdYbS5VTy92NIUbeDI1qyggi+JYh5op9IFlcQ= github.com/axiomhq/hyperloglog v0.0.0-20240319100328-84253e514e02/go.mod h1:k08r+Yj1PRAmuayFiRK6MYuR5Ve4IuZtTfxErMIh0+c= github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= +github.com/coder/websocket v1.8.15 h1:6B2JPeOGlpff2Uz6vOEH1Vzpi0iUz20A+lPVhPHtNUA= +github.com/coder/websocket v1.8.15/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/creachadair/msync v0.7.1 h1:SeZmuEBXQPe5GqV/C94ER7QIZPwtvFbeQiykzt/7uho= github.com/creachadair/msync v0.7.1/go.mod h1:8CcFlLsSujfHE5wWm19uUBLHIPDAUr6LXDwneVMO008= +github.com/creachadair/msync v0.10.1 h1:14jT5Ujob64Zp2D3ZcUidayDMoXikhmYN8xBxEuPKPk= +github.com/creachadair/msync v0.10.1/go.mod h1:dFf4Z0cxE2nibFmAdq5OqTuGn++GgEqA9JuKH+7ceSA= github.com/creachadair/taskgroup v0.13.2 h1:3KyqakBuFsm3KkXi/9XIb0QcA8tEzLHLgaoidf0MdVc= github.com/creachadair/taskgroup v0.13.2/go.mod h1:i3V1Zx7H8RjwljUEeUWYT30Lmb9poewSb2XI1yTwD0g= github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0= github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa h1:h8TfIT1xc8FWbwwpmHn1J5i43Y0uZP97GqasGCzSRJk= github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa/go.mod h1:Nx87SkVqTKd8UtT+xu7sM/l+LgXs6c0aHrlKusR+2EQ= +github.com/dblohm7/wingoes v0.0.0-20260526185140-fb298caac7ca h1:h1Awca4lQOspNR/2eeo04Ricn5NixDX9mb17WSAgLhQ= +github.com/dblohm7/wingoes v0.0.0-20260526185140-fb298caac7ca/go.mod h1:2TGl1jRJrRpbzykmg7asHm3h08TqutUgQqY5v9k/g3c= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc h1:8WFBn63wegobsYAX0YjD+8suexZDga5CctH4CCTx2+8= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e h1:vUmf0yezR0y7jJ5pceLHthLaYf4bA5T14B6q39S4q2Q= @@ -66,18 +88,26 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q= +github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gaissmai/bart v0.18.0 h1:jQLBT/RduJu0pv/tLwXE+xKPgtWJejbxuXAR+wLJafo= github.com/gaissmai/bart v0.18.0/go.mod h1:JJzMAhNF5Rjo4SF4jWBrANuJfqY+FvsFhW7t1UZJ+XY= +github.com/gaissmai/bart v0.29.0 h1:wO6HGE8g9YE0Wm0bCpYxwRzfQ4+fbJKOhL64e5ACGCI= +github.com/gaissmai/bart v0.29.0/go.mod h1:GREWQfTLRWz/c5FTOsIw+KkscuFkIV5t8Rp7Nd1Td5c= github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced h1:Q311OHjMh/u5E2TITc++WlTP5We0xNseRMkHDyvhW7I= github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= +github.com/go-json-experiment/json v0.0.0-20260820222146-c27c302e5fc3 h1:UADEEmDKgfXbtnGJZ97beY5XLo9ZechG1nlU4KnRrkE= +github.com/go-json-experiment/json v0.0.0-20260820222146-c27c302e5fc3/go.mod h1:tphK2c80bpPhMOI4v6bIc2xWywPfbqi1Z06+RcrMkDg= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737 h1:cf60tHxREO3g1nroKr2osU3JWZsJzkfi7rEg+oAB0Lo= github.com/go4org/plan9netshell v0.0.0-20250324183649-788daa080737/go.mod h1:MIS0jDzbU/vuM9MC4YnBITCv+RYuTRq8dJzmCrFsK9g= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU= +github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ= +github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= @@ -104,8 +134,12 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jsimonetti/rtnetlink v1.4.0 h1:Z1BF0fRgcETPEa0Kt0MRk3yV5+kF1FWTni6KUFKrq2I= github.com/jsimonetti/rtnetlink v1.4.0/go.mod h1:5W1jDvWdnthFJ7fxYX1GMK07BUpI4oskfOqvPteYS6E= +github.com/jsimonetti/rtnetlink v1.4.2 h1:Df9w9TZ3npHTyDn0Ev9e1uzmN2odmXd0QX+J5GTEn90= +github.com/jsimonetti/rtnetlink v1.4.2/go.mod h1:92s6LJdE+1iOrw+F2/RO7LYI2Qd8pPpFNNUYW06gcoM= github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= +github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= @@ -118,10 +152,14 @@ github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy5 github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o= github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 h1:A1Cq6Ysb0GM0tpKMbdCXCIfBclan4oHk1Jb+Hrejirg= github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42/go.mod h1:BB4YCPDOzfy7FniQ/lxuYQ3dgmM2cZumHbK8RpTjN2o= +github.com/mdlayher/netlink v1.11.2 h1:HKh2jqe+omdSWcQ88nrT7INE61B0NXfiSPFdgL4YbNI= +github.com/mdlayher/netlink v1.11.2/go.mod h1:uT2Yc/QLaZubzDpZIBi9d4GoeLwtp3x1AMeqSRrK2sA= github.com/mdlayher/sdnotify v1.0.0 h1:Ma9XeLVN/l0qpyx1tNeMSeTjCPH6NtuD6/N9XdTlQ3c= github.com/mdlayher/sdnotify v1.0.0/go.mod h1:HQUmpM4XgYkhDLtd+Uad8ZFK1T9D5+pNxnXQjCeJlGE= github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI= github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI= +github.com/mdlayher/socket v0.7.0 h1:qVREPVwtUMg17pwvveQxpurq0PVisMxi3FGgpsorMYQ= +github.com/mdlayher/socket v0.7.0/go.mod h1:f7iKql2EK/rfsWYDKofKjk2Ig7I+6HQWdMIdn1tO4A4= github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= @@ -134,6 +172,8 @@ github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0= github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU= +github.com/pires/go-proxyproto v0.15.0 h1:dTshmNbFm/D+0+sbrxUuddPOZ5Y0B7c5NhtsBkm6LqI= +github.com/pires/go-proxyproto v0.15.0/go.mod h1:OXsCrKwrK2tXS9YrI5tkHx5xaQlO8FH3lFW76orFh24= github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4= @@ -146,24 +186,34 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs= +github.com/safchain/ethtool v0.7.0 h1:rlJzfDetsVvT61uz8x1YIcFn12akMfuPulHtZjtb7Is= +github.com/safchain/ethtool v0.7.0/go.mod h1:MenQKEjXdfkjD3mp2QdCk8B/hwvkrlOTm/FD4gTpFxQ= github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e h1:PtWT87weP5LWHEY//SWsYkSO3RWRZo4OSWagh3YD2vQ= github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e/go.mod h1:XrBNfAFN+pwoWuksbFS9Ccxnopa15zJGgXRFN90l3K4= +github.com/tailscale/certstore v0.1.1-0.20260409135935-3638fb84b77d h1:JcGKBZAL7ePLwOhUdN8qGQZlP5GueEiIZwY7R62pejE= +github.com/tailscale/certstore v0.1.1-0.20260409135935-3638fb84b77d/go.mod h1:XrBNfAFN+pwoWuksbFS9Ccxnopa15zJGgXRFN90l3K4= 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/golang-x-crypto v0.0.0-20250404221719-a5573b049869 h1:SRL6irQkKGQKKLzvQP/ke/2ZuB7Py5+XuqtOgSj+iMM= github.com/tailscale/golang-x-crypto v0.0.0-20250404221719-a5573b049869/go.mod h1:ikbF+YT089eInTp9f2vmvy4+ZVnW5hzX1q2WknxSprQ= github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29XwJucQo73FrleVK6t4kYz4NVhp34Yw= github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8= +github.com/tailscale/hujson v0.0.0-20260727124030-b80ff77dac4f h1:9hiVElpCmKzsBKQHkBqZ8LGzt82iLfM8egxr4sew+Ys= +github.com/tailscale/hujson v0.0.0-20260727124030-b80ff77dac4f/go.mod h1:8/zr1Tv0+cKpVtGCEB/7YfRXr2TszsMxMXLaT8YuBgU= github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 h1:uFsXVBE9Qr4ZoF094vE6iYTLDl0qCiKzYXlL6UeWObU= github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc h1:24heQPtnFR+yfntqhI3oAu9i27nEojcQ4NuBQOo5ZFA= github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc/go.mod h1:f93CXfllFsO9ZQVq+Zocb1Gp4G5Fz0b0rXHLOzt/Djc= github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:UBPHPtv8+nEAy2PD8RyAhOYvau1ek0HDJqLS/Pysi14= github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= +github.com/tailscale/web-client-prebuilt v0.0.0-20260917222731-e0ed2d0d0fea h1:ah5jt6ZnxMvNclt6kBBoLcMpLLjMA44PTsnov2y7gpU= +github.com/tailscale/web-client-prebuilt v0.0.0-20260917222731-e0ed2d0d0fea/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6 h1:l10Gi6w9jxvinoiq15g8OToDdASBni4CyJOdHY1Hr8M= github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6/go.mod h1:ZXRML051h7o4OcI0d3AaILDIad/Xw0IkXaHM17dic1Y= github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da h1:jVRUZPRs9sqyKlYHHzHjAqKN+6e/Vog6NpHYeNPJqOw= github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4= +github.com/tailscale/wireguard-go v0.0.0-20260928213032-417aef361226 h1:v3Lpj2iHPWQDqeCwemQPz4fWweIEMLqBkwJqCjRyJQc= +github.com/tailscale/wireguard-go v0.0.0-20260928213032-417aef361226/go.mod h1:rUelGmuK4UnSJYM5gl5Mknp6YbwwcL8+VAPMhNYe+jg= github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e h1:zOGKqN5D5hHhiYUp091JqK7DPCqSARyUfduhGUY8Bek= github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e/go.mod h1:orPd6JZXXRyuDusYilywte7k094d7dycXXU5YnWsrwg= github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA= @@ -180,10 +230,16 @@ go4.org/mem v0.0.0-20240501181205-ae6ca9944745 h1:Tl++JLUCe4sxGu8cTpDzRLd3tN7US4 go4.org/mem v0.0.0-20240501181205-ae6ca9944745/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= +go4.org/netipx v0.0.0-20260823151212-3075585bcbeb h1:XBM4hvfwGAttkkiTIFfeigdfcL1xIfdKXqFdgiHGtDs= +go4.org/netipx v0.0.0-20260823151212-3075585bcbeb/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= +golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba h1:Ck8QetSgk912qxWLMCKxd0in+aiyBQyDSMae6e/xmpU= +golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba/go.mod h1:50RgIsmK7OwqzTTeqcSXQW8SswW0o8fRcDxmqGluJ8E= golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= @@ -192,31 +248,49 @@ golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues= +golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.37.0 h1:JUlcxA8oAtauLfiH8FX2/FkAWHAdi0QtGCGc+hofE98= +golang.org/x/oauth2 v0.37.0/go.mod h1:IxwZNxUULJmpBFf9K/9NTMSIfZZuvuTy1gGxhigP/58= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= +golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE= +golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.16.0 h1:vMb6ptszcQMkcwiRTAuNNU50gom6++Q/6gY2hDM6VDE= +golang.org/x/time v0.16.0/go.mod h1:rVKOqvZeKvrDKTQiAHJ7wmwP0RzleSphoEA9RcdLA0s= golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE= golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI= +golang.zx2c4.com/wireguard/windows v1.0.1 h1:eOxiDVbywPC+ZQqvdCK7x+ZwWXKbYv50TtH8ysFIbw8= +golang.zx2c4.com/wireguard/windows v1.0.1/go.mod h1:+fbT3FFdX4zzYDLwJh5+HPEcNN/3HyNdzhNSVsQM+zs= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 h1:2gap+Kh/3F47cO6hAu3idFvsJ0ue6TRcEi2IUkv/F8k= gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM= +gvisor.dev/gvisor v0.0.0-20260915211658-a6f909f08a72 h1:EytKYr5WrVs+Aah/0xDO8ZAZZzS/iTEVC8ln4ipDbL0= +gvisor.dev/gvisor v0.0.0-20260915211658-a6f909f08a72/go.mod h1:8aLQqUBHDH8fY5y60lzmwDpMMbQCcT3EBfoSwhfaGCY= honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0 h1:5SXjd4ET5dYijLaf0O3aOenC0Z4ZafIWSpjUzsQaNho= honnef.co/go/tools v0.7.0-0.dev.0.20251022135355-8273271481d0/go.mod h1:EPDDhEZqVHhWuPI5zPAsjU0U7v9xNIWjoOVyZ5ZcniQ= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= @@ -225,3 +299,5 @@ software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= tailscale.com v1.94.1 h1:0dAst/ozTuFkgmxZULc3oNwR9+qPIt5ucvzH7kaM0Jw= tailscale.com v1.94.1/go.mod h1:gLnVrEOP32GWvroaAHHGhjSGMPJ1i4DvqNwEg+Yuov4= +tailscale.com v1.104.1 h1:9GNOm9Izqll9RH5jA5NWcLiCzXi/WtqY4EHQY2Dy2zk= +tailscale.com v1.104.1/go.mod h1:Cb1XjScRgSOeRD7NW6uCEznme782WiOU9IxqyTWoRf0= diff --git a/vendor/filippo.io/edwards25519/README.md b/vendor/filippo.io/edwards25519/README.md index 24e2457..dcdd8d8 100644 --- a/vendor/filippo.io/edwards25519/README.md +++ b/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/vendor/filippo.io/edwards25519/doc.go b/vendor/filippo.io/edwards25519/doc.go index ab6aaeb..dd2deb6 100644 --- a/vendor/filippo.io/edwards25519/doc.go +++ b/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/vendor/filippo.io/edwards25519/extra.go b/vendor/filippo.io/edwards25519/extra.go index d152d68..ee9b5ca 100644 --- a/vendor/filippo.io/edwards25519/extra.go +++ b/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/vendor/filippo.io/edwards25519/field/fe.go b/vendor/filippo.io/edwards25519/field/fe.go index 5518ef2..4d52cc1 100644 --- a/vendor/filippo.io/edwards25519/field/fe.go +++ b/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/vendor/filippo.io/edwards25519/field/fe_amd64.go b/vendor/filippo.io/edwards25519/field/fe_amd64.go index edcf163..00bf8f4 100644 --- a/vendor/filippo.io/edwards25519/field/fe_amd64.go +++ b/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/vendor/filippo.io/edwards25519/field/fe_amd64.s b/vendor/filippo.io/edwards25519/field/fe_amd64.s index 293f013..5e06e24 100644 --- a/vendor/filippo.io/edwards25519/field/fe_amd64.s +++ b/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/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go b/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go index ddb6c9b..4b81f25 100644 --- a/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go +++ b/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/vendor/filippo.io/edwards25519/field/fe_arm64.go b/vendor/filippo.io/edwards25519/field/fe_arm64.go deleted file mode 100644 index af459ef..0000000 --- a/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/vendor/filippo.io/edwards25519/field/fe_arm64.s b/vendor/filippo.io/edwards25519/field/fe_arm64.s deleted file mode 100644 index 3126a43..0000000 --- a/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/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go b/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go deleted file mode 100644 index 234a5b2..0000000 --- a/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/vendor/filippo.io/edwards25519/field/fe_generic.go b/vendor/filippo.io/edwards25519/field/fe_generic.go index 86f5fd9..ef1f15a 100644 --- a/vendor/filippo.io/edwards25519/field/fe_generic.go +++ b/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/vendor/filippo.io/edwards25519/pull.sh b/vendor/filippo.io/edwards25519/pull.sh new file mode 100644 index 0000000..f6217c9 --- /dev/null +++ b/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/vendor/filippo.io/edwards25519/scalar.go b/vendor/filippo.io/edwards25519/scalar.go index 3fd1653..f08b262 100644 --- a/vendor/filippo.io/edwards25519/scalar.go +++ b/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/vendor/filippo.io/edwards25519/tables.go b/vendor/filippo.io/edwards25519/tables.go index 83234bb..4a2b54e 100644 --- a/vendor/filippo.io/edwards25519/tables.go +++ b/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/vendor/github.com/alexbrainman/sspi/internal/common/common.go b/vendor/github.com/alexbrainman/sspi/internal/common/common.go index 7ccf4d5..a5b64ac 100644 --- a/vendor/github.com/alexbrainman/sspi/internal/common/common.go +++ b/vendor/github.com/alexbrainman/sspi/internal/common/common.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows // +build windows package common @@ -41,19 +42,34 @@ func BuildAuthIdentity(domain, username, password string) (*sspi.SEC_WINNT_AUTH_ } func UpdateContext(c *sspi.Context, dst, src []byte, targetName *uint16) (authCompleted bool, n int, err error) { - var inBuf, outBuf [1]sspi.SecBuffer + return UpdateContextWithChannelBindings(c, dst, src, nil, targetName) +} + +// UpdateContextWithChannelBindings performs SSPI context update with optional channel binding tokens. +func UpdateContextWithChannelBindings(c *sspi.Context, dst, src, channelBindings []byte, targetName *uint16) (authCompleted bool, n int, err error) { + var inBuf [2]sspi.SecBuffer + inBuf[0].Set(sspi.SECBUFFER_TOKEN, src) inBufs := &sspi.SecBufferDesc{ Version: sspi.SECBUFFER_VERSION, BuffersCount: 1, Buffers: &inBuf[0], } + + if len(channelBindings) > 0 { + // With channel bindings: TOKEN buffer + CHANNEL_BINDINGS buffer + inBuf[1].Set(sspi.SECBUFFER_CHANNEL_BINDINGS, channelBindings) + inBufs.BuffersCount = 2 + } + + var outBuf [1]sspi.SecBuffer outBuf[0].Set(sspi.SECBUFFER_TOKEN, dst) outBufs := &sspi.SecBufferDesc{ Version: sspi.SECBUFFER_VERSION, BuffersCount: 1, Buffers: &outBuf[0], } + ret := c.Update(targetName, outBufs, inBufs) switch ret { case sspi.SEC_E_OK: diff --git a/vendor/github.com/alexbrainman/sspi/syscall.go b/vendor/github.com/alexbrainman/sspi/syscall.go index 04660df..27aa4f8 100644 --- a/vendor/github.com/alexbrainman/sspi/syscall.go +++ b/vendor/github.com/alexbrainman/sspi/syscall.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build windows // +build windows package sspi @@ -96,19 +97,20 @@ type CredHandle struct { const ( SECURITY_NATIVE_DREP = 16 - SECBUFFER_DATA = 1 - SECBUFFER_TOKEN = 2 - SECBUFFER_PKG_PARAMS = 3 - SECBUFFER_MISSING = 4 - SECBUFFER_EXTRA = 5 - SECBUFFER_STREAM_TRAILER = 6 - SECBUFFER_STREAM_HEADER = 7 - SECBUFFER_PADDING = 9 - SECBUFFER_STREAM = 10 - SECBUFFER_READONLY = 0x80000000 - SECBUFFER_ATTRMASK = 0xf0000000 - SECBUFFER_VERSION = 0 - SECBUFFER_EMPTY = 0 + SECBUFFER_DATA = 1 + SECBUFFER_TOKEN = 2 + SECBUFFER_PKG_PARAMS = 3 + SECBUFFER_MISSING = 4 + SECBUFFER_EXTRA = 5 + SECBUFFER_STREAM_TRAILER = 6 + SECBUFFER_STREAM_HEADER = 7 + SECBUFFER_PADDING = 9 + SECBUFFER_STREAM = 10 + SECBUFFER_CHANNEL_BINDINGS = 14 + SECBUFFER_READONLY = 0x80000000 + SECBUFFER_ATTRMASK = 0xf0000000 + SECBUFFER_VERSION = 0 + SECBUFFER_EMPTY = 0 ISC_REQ_DELEGATE = 1 ISC_REQ_MUTUAL_AUTH = 2 diff --git a/vendor/github.com/aws/aws-sdk-go-v2/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/NOTICE.txt b/vendor/github.com/aws/aws-sdk-go-v2/NOTICE.txt deleted file mode 100644 index 899129e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/NOTICE.txt +++ /dev/null @@ -1,3 +0,0 @@ -AWS SDK for Go -Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. -Copyright 2014-2015 Stripe, Inc. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/accountid_endpoint_mode.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/accountid_endpoint_mode.go deleted file mode 100644 index 6504a21..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/accountid_endpoint_mode.go +++ /dev/null @@ -1,18 +0,0 @@ -package aws - -// AccountIDEndpointMode controls how a resolved AWS account ID is handled for endpoint routing. -type AccountIDEndpointMode string - -const ( - // AccountIDEndpointModeUnset indicates the AWS account ID will not be used for endpoint routing - AccountIDEndpointModeUnset AccountIDEndpointMode = "" - - // AccountIDEndpointModePreferred indicates the AWS account ID will be used for endpoint routing if present - AccountIDEndpointModePreferred = "preferred" - - // AccountIDEndpointModeRequired indicates an error will be returned if the AWS account ID is not resolved from identity - AccountIDEndpointModeRequired = "required" - - // AccountIDEndpointModeDisabled indicates the AWS account ID will be ignored during endpoint routing - AccountIDEndpointModeDisabled = "disabled" -) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/checksum.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/checksum.go deleted file mode 100644 index 4152caa..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/checksum.go +++ /dev/null @@ -1,33 +0,0 @@ -package aws - -// RequestChecksumCalculation controls request checksum calculation workflow -type RequestChecksumCalculation int - -const ( - // RequestChecksumCalculationUnset is the unset value for RequestChecksumCalculation - RequestChecksumCalculationUnset RequestChecksumCalculation = iota - - // RequestChecksumCalculationWhenSupported indicates request checksum will be calculated - // if the operation supports input checksums - RequestChecksumCalculationWhenSupported - - // RequestChecksumCalculationWhenRequired indicates request checksum will be calculated - // if required by the operation or if user elects to set a checksum algorithm in request - RequestChecksumCalculationWhenRequired -) - -// ResponseChecksumValidation controls response checksum validation workflow -type ResponseChecksumValidation int - -const ( - // ResponseChecksumValidationUnset is the unset value for ResponseChecksumValidation - ResponseChecksumValidationUnset ResponseChecksumValidation = iota - - // ResponseChecksumValidationWhenSupported indicates response checksum will be validated - // if the operation supports output checksums - ResponseChecksumValidationWhenSupported - - // ResponseChecksumValidationWhenRequired indicates response checksum will only - // be validated if the operation requires output checksum validation - ResponseChecksumValidationWhenRequired -) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go deleted file mode 100644 index 3219517..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go +++ /dev/null @@ -1,250 +0,0 @@ -package aws - -import ( - "net/http" - - smithybearer "github.com/aws/smithy-go/auth/bearer" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// HTTPClient provides the interface to provide custom HTTPClients. Generally -// *http.Client is sufficient for most use cases. The HTTPClient should not -// follow 301 or 302 redirects. -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) -} - -// A Config provides service configuration for service clients. -type Config struct { - // The region to send requests to. This parameter is required and must - // be configured globally or on a per-client basis unless otherwise - // noted. A full list of regions is found in the "Regions and Endpoints" - // document. - // - // See http://docs.aws.amazon.com/general/latest/gr/rande.html for - // information on AWS regions. - Region string - - // The credentials object to use when signing requests. - // Use the LoadDefaultConfig to load configuration from all the SDK's supported - // sources, and resolve credentials using the SDK's default credential chain. - Credentials CredentialsProvider - - // The Bearer Authentication token provider to use for authenticating API - // operation calls with a Bearer Authentication token. The API clients and - // operation must support Bearer Authentication scheme in order for the - // token provider to be used. API clients created with NewFromConfig will - // automatically be configured with this option, if the API client support - // Bearer Authentication. - // - // The SDK's config.LoadDefaultConfig can automatically populate this - // option for external configuration options such as SSO session. - // https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html - BearerAuthTokenProvider smithybearer.TokenProvider - - // The HTTP Client the SDK's API clients will use to invoke HTTP requests. - // The SDK defaults to a BuildableClient allowing API clients to create - // copies of the HTTP Client for service specific customizations. - // - // Use a (*http.Client) for custom behavior. Using a custom http.Client - // will prevent the SDK from modifying the HTTP client. - HTTPClient HTTPClient - - // An endpoint resolver that can be used to provide or override an endpoint - // for the given service and region. - // - // See the `aws.EndpointResolver` documentation for additional usage - // information. - // - // Deprecated: See Config.EndpointResolverWithOptions - EndpointResolver EndpointResolver - - // An endpoint resolver that can be used to provide or override an endpoint - // for the given service and region. - // - // When EndpointResolverWithOptions is specified, it will be used by a - // service client rather than using EndpointResolver if also specified. - // - // See the `aws.EndpointResolverWithOptions` documentation for additional - // usage information. - // - // Deprecated: with the release of endpoint resolution v2 in API clients, - // EndpointResolver and EndpointResolverWithOptions are deprecated. - // Providing a value for this field will likely prevent you from using - // newer endpoint-related service features. See API client options - // EndpointResolverV2 and BaseEndpoint. - EndpointResolverWithOptions EndpointResolverWithOptions - - // RetryMaxAttempts specifies the maximum number attempts an API client - // will call an operation that fails with a retryable error. - // - // API Clients will only use this value to construct a retryer if the - // Config.Retryer member is not nil. This value will be ignored if - // Retryer is not nil. - RetryMaxAttempts int - - // RetryMode specifies the retry model the API client will be created with. - // - // API Clients will only use this value to construct a retryer if the - // Config.Retryer member is not nil. This value will be ignored if - // Retryer is not nil. - RetryMode RetryMode - - // Retryer is a function that provides a Retryer implementation. A Retryer - // guides how HTTP requests should be retried in case of recoverable - // failures. When nil the API client will use a default retryer. - // - // In general, the provider function should return a new instance of a - // Retryer if you are attempting to provide a consistent Retryer - // configuration across all clients. This will ensure that each client will - // be provided a new instance of the Retryer implementation, and will avoid - // issues such as sharing the same retry token bucket across services. - // - // If not nil, RetryMaxAttempts, and RetryMode will be ignored by API - // clients. - Retryer func() Retryer - - // ConfigSources are the sources that were used to construct the Config. - // Allows for additional configuration to be loaded by clients. - ConfigSources []interface{} - - // APIOptions provides the set of middleware mutations modify how the API - // client requests will be handled. This is useful for adding additional - // tracing data to a request, or changing behavior of the SDK's client. - APIOptions []func(*middleware.Stack) error - - // The logger writer interface to write logging messages to. Defaults to - // standard error. - Logger logging.Logger - - // Configures the events that will be sent to the configured logger. This - // can be used to configure the logging of signing, retries, request, and - // responses of the SDK clients. - // - // See the ClientLogMode type documentation for the complete set of logging - // modes and available configuration. - ClientLogMode ClientLogMode - - // The configured DefaultsMode. If not specified, service clients will - // default to legacy. - // - // Supported modes are: auto, cross-region, in-region, legacy, mobile, - // standard - DefaultsMode DefaultsMode - - // The RuntimeEnvironment configuration, only populated if the DefaultsMode - // is set to DefaultsModeAuto and is initialized by - // `config.LoadDefaultConfig`. You should not populate this structure - // programmatically, or rely on the values here within your applications. - RuntimeEnvironment RuntimeEnvironment - - // AppId is an optional application specific identifier that can be set. - // When set it will be appended to the User-Agent header of every request - // in the form of App/{AppId}. This variable is sourced from environment - // variable AWS_SDK_UA_APP_ID or the shared config profile attribute sdk_ua_app_id. - // See https://docs.aws.amazon.com/sdkref/latest/guide/settings-reference.html for - // more information on environment variables and shared config settings. - AppID string - - // BaseEndpoint is an intermediary transfer location to a service specific - // BaseEndpoint on a service's Options. - BaseEndpoint *string - - // DisableRequestCompression toggles if an operation request could be - // compressed or not. Will be set to false by default. This variable is sourced from - // environment variable AWS_DISABLE_REQUEST_COMPRESSION or the shared config profile attribute - // disable_request_compression - DisableRequestCompression bool - - // RequestMinCompressSizeBytes sets the inclusive min bytes of a request body that could be - // compressed. Will be set to 10240 by default and must be within 0 and 10485760 bytes inclusively. - // This variable is sourced from environment variable AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES or - // the shared config profile attribute request_min_compression_size_bytes - RequestMinCompressSizeBytes int64 - - // Controls how a resolved AWS account ID is handled for endpoint routing. - AccountIDEndpointMode AccountIDEndpointMode - - // RequestChecksumCalculation determines when request checksum calculation is performed. - // - // There are two possible values for this setting: - // - // 1. RequestChecksumCalculationWhenSupported (default): The checksum is always calculated - // if the operation supports it, regardless of whether the user sets an algorithm in the request. - // - // 2. RequestChecksumCalculationWhenRequired: The checksum is only calculated if the user - // explicitly sets a checksum algorithm in the request. - // - // This setting is sourced from the environment variable AWS_REQUEST_CHECKSUM_CALCULATION - // or the shared config profile attribute "request_checksum_calculation". - RequestChecksumCalculation RequestChecksumCalculation - - // ResponseChecksumValidation determines when response checksum validation is performed - // - // There are two possible values for this setting: - // - // 1. ResponseChecksumValidationWhenSupported (default): The checksum is always validated - // if the operation supports it, regardless of whether the user sets the validation mode to ENABLED in request. - // - // 2. ResponseChecksumValidationWhenRequired: The checksum is only validated if the user - // explicitly sets the validation mode to ENABLED in the request - // This variable is sourced from environment variable AWS_RESPONSE_CHECKSUM_VALIDATION or - // the shared config profile attribute "response_checksum_validation". - ResponseChecksumValidation ResponseChecksumValidation - - // Registry of HTTP interceptors. - Interceptors smithyhttp.InterceptorRegistry - - // Priority list of preferred auth scheme IDs. - AuthSchemePreference []string - - // ServiceOptions provides service specific configuration options that will be applied - // when constructing clients for specific services. Each callback function receives the service ID - // and the service's Options struct, allowing for dynamic configuration based on the service. - ServiceOptions []func(string, any) -} - -// NewConfig returns a new Config pointer that can be chained with builder -// methods to set multiple configuration values inline without using pointers. -func NewConfig() *Config { - return &Config{} -} - -// Copy will return a shallow copy of the Config object. -func (c Config) Copy() Config { - cp := c - return cp -} - -// EndpointDiscoveryEnableState indicates if endpoint discovery is -// enabled, disabled, auto or unset state. -// -// Default behavior (Auto or Unset) indicates operations that require endpoint -// discovery will use Endpoint Discovery by default. Operations that -// optionally use Endpoint Discovery will not use Endpoint Discovery -// unless EndpointDiscovery is explicitly enabled. -type EndpointDiscoveryEnableState uint - -// Enumeration values for EndpointDiscoveryEnableState -const ( - // EndpointDiscoveryUnset represents EndpointDiscoveryEnableState is unset. - // Users do not need to use this value explicitly. The behavior for unset - // is the same as for EndpointDiscoveryAuto. - EndpointDiscoveryUnset EndpointDiscoveryEnableState = iota - - // EndpointDiscoveryAuto represents an AUTO state that allows endpoint - // discovery only when required by the api. This is the default - // configuration resolved by the client if endpoint discovery is neither - // enabled or disabled. - EndpointDiscoveryAuto // default state - - // EndpointDiscoveryDisabled indicates client MUST not perform endpoint - // discovery even when required. - EndpointDiscoveryDisabled - - // EndpointDiscoveryEnabled indicates client MUST always perform endpoint - // discovery if supported for the operation. - EndpointDiscoveryEnabled -) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/context.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/context.go deleted file mode 100644 index 4d8e26e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/context.go +++ /dev/null @@ -1,22 +0,0 @@ -package aws - -import ( - "context" - "time" -) - -type suppressedContext struct { - context.Context -} - -func (s *suppressedContext) Deadline() (deadline time.Time, ok bool) { - return time.Time{}, false -} - -func (s *suppressedContext) Done() <-chan struct{} { - return nil -} - -func (s *suppressedContext) Err() error { - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/credential_cache.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/credential_cache.go deleted file mode 100644 index 623890e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/credential_cache.go +++ /dev/null @@ -1,235 +0,0 @@ -package aws - -import ( - "context" - "fmt" - "sync/atomic" - "time" - - sdkrand "github.com/aws/aws-sdk-go-v2/internal/rand" - "github.com/aws/aws-sdk-go-v2/internal/sync/singleflight" -) - -// CredentialsCacheOptions are the options -type CredentialsCacheOptions struct { - - // ExpiryWindow will allow the credentials to trigger refreshing prior to - // the credentials actually expiring. This is beneficial so race conditions - // with expiring credentials do not cause request to fail unexpectedly - // due to ExpiredTokenException exceptions. - // - // An ExpiryWindow of 10s would cause calls to IsExpired() to return true - // 10 seconds before the credentials are actually expired. This can cause an - // increased number of requests to refresh the credentials to occur. - // - // If ExpiryWindow is 0 or less it will be ignored. - ExpiryWindow time.Duration - - // ExpiryWindowJitterFrac provides a mechanism for randomizing the - // expiration of credentials within the configured ExpiryWindow by a random - // percentage. Valid values are between 0.0 and 1.0. - // - // As an example if ExpiryWindow is 60 seconds and ExpiryWindowJitterFrac - // is 0.5 then credentials will be set to expire between 30 to 60 seconds - // prior to their actual expiration time. - // - // If ExpiryWindow is 0 or less then ExpiryWindowJitterFrac is ignored. - // If ExpiryWindowJitterFrac is 0 then no randomization will be applied to the window. - // If ExpiryWindowJitterFrac < 0 the value will be treated as 0. - // If ExpiryWindowJitterFrac > 1 the value will be treated as 1. - ExpiryWindowJitterFrac float64 -} - -// CredentialsCache provides caching and concurrency safe credentials retrieval -// via the provider's retrieve method. -// -// CredentialsCache will look for optional interfaces on the Provider to adjust -// how the credential cache handles credentials caching. -// -// - HandleFailRefreshCredentialsCacheStrategy - Allows provider to handle -// credential refresh failures. This could return an updated Credentials -// value, or attempt another means of retrieving credentials. -// -// - AdjustExpiresByCredentialsCacheStrategy - Allows provider to adjust how -// credentials Expires is modified. This could modify how the Credentials -// Expires is adjusted based on the CredentialsCache ExpiryWindow option. -// Such as providing a floor not to reduce the Expires below. -type CredentialsCache struct { - provider CredentialsProvider - - options CredentialsCacheOptions - creds atomic.Value - sf singleflight.Group -} - -// NewCredentialsCache returns a CredentialsCache that wraps provider. Provider -// is expected to not be nil. A variadic list of one or more functions can be -// provided to modify the CredentialsCache configuration. This allows for -// configuration of credential expiry window and jitter. -func NewCredentialsCache(provider CredentialsProvider, optFns ...func(options *CredentialsCacheOptions)) *CredentialsCache { - options := CredentialsCacheOptions{} - - for _, fn := range optFns { - fn(&options) - } - - if options.ExpiryWindow < 0 { - options.ExpiryWindow = 0 - } - - if options.ExpiryWindowJitterFrac < 0 { - options.ExpiryWindowJitterFrac = 0 - } else if options.ExpiryWindowJitterFrac > 1 { - options.ExpiryWindowJitterFrac = 1 - } - - return &CredentialsCache{ - provider: provider, - options: options, - } -} - -// Retrieve returns the credentials. If the credentials have already been -// retrieved, and not expired the cached credentials will be returned. If the -// credentials have not been retrieved yet, or expired the provider's Retrieve -// method will be called. -// -// Returns and error if the provider's retrieve method returns an error. -func (p *CredentialsCache) Retrieve(ctx context.Context) (Credentials, error) { - if creds, ok := p.getCreds(); ok && !creds.Expired() { - return creds, nil - } - - resCh := p.sf.DoChan("", func() (interface{}, error) { - return p.singleRetrieve(&suppressedContext{ctx}) - }) - select { - case res := <-resCh: - return res.Val.(Credentials), res.Err - case <-ctx.Done(): - return Credentials{}, &RequestCanceledError{Err: ctx.Err()} - } -} - -func (p *CredentialsCache) singleRetrieve(ctx context.Context) (interface{}, error) { - currCreds, ok := p.getCreds() - if ok && !currCreds.Expired() { - return currCreds, nil - } - - newCreds, err := p.provider.Retrieve(ctx) - if err != nil { - handleFailToRefresh := defaultHandleFailToRefresh - if cs, ok := p.provider.(HandleFailRefreshCredentialsCacheStrategy); ok { - handleFailToRefresh = cs.HandleFailToRefresh - } - newCreds, err = handleFailToRefresh(ctx, currCreds, err) - if err != nil { - return Credentials{}, fmt.Errorf("failed to refresh cached credentials, %w", err) - } - } - - if newCreds.CanExpire && p.options.ExpiryWindow > 0 { - adjustExpiresBy := defaultAdjustExpiresBy - if cs, ok := p.provider.(AdjustExpiresByCredentialsCacheStrategy); ok { - adjustExpiresBy = cs.AdjustExpiresBy - } - - randFloat64, err := sdkrand.CryptoRandFloat64() - if err != nil { - return Credentials{}, fmt.Errorf("failed to get random provider, %w", err) - } - - var jitter time.Duration - if p.options.ExpiryWindowJitterFrac > 0 { - jitter = time.Duration(randFloat64 * - p.options.ExpiryWindowJitterFrac * float64(p.options.ExpiryWindow)) - } - - newCreds, err = adjustExpiresBy(newCreds, -(p.options.ExpiryWindow - jitter)) - if err != nil { - return Credentials{}, fmt.Errorf("failed to adjust credentials expires, %w", err) - } - } - - p.creds.Store(&newCreds) - return newCreds, nil -} - -// getCreds returns the currently stored credentials and true. Returning false -// if no credentials were stored. -func (p *CredentialsCache) getCreds() (Credentials, bool) { - v := p.creds.Load() - if v == nil { - return Credentials{}, false - } - - c := v.(*Credentials) - if c == nil || !c.HasKeys() { - return Credentials{}, false - } - - return *c, true -} - -// ProviderSources returns a list of where the underlying credential provider -// has been sourced, if available. Returns empty if the provider doesn't implement -// the interface -func (p *CredentialsCache) ProviderSources() []CredentialSource { - asSource, ok := p.provider.(CredentialProviderSource) - if !ok { - return []CredentialSource{} - } - return asSource.ProviderSources() -} - -// Invalidate will invalidate the cached credentials. The next call to Retrieve -// will cause the provider's Retrieve method to be called. -func (p *CredentialsCache) Invalidate() { - p.creds.Store((*Credentials)(nil)) -} - -// IsCredentialsProvider returns whether credential provider wrapped by CredentialsCache -// matches the target provider type. -func (p *CredentialsCache) IsCredentialsProvider(target CredentialsProvider) bool { - return IsCredentialsProvider(p.provider, target) -} - -// HandleFailRefreshCredentialsCacheStrategy is an interface for -// CredentialsCache to allow CredentialsProvider how failed to refresh -// credentials is handled. -type HandleFailRefreshCredentialsCacheStrategy interface { - // Given the previously cached Credentials, if any, and refresh error, may - // returns new or modified set of Credentials, or error. - // - // Credential caches may use default implementation if nil. - HandleFailToRefresh(context.Context, Credentials, error) (Credentials, error) -} - -// defaultHandleFailToRefresh returns the passed in error. -func defaultHandleFailToRefresh(ctx context.Context, _ Credentials, err error) (Credentials, error) { - return Credentials{}, err -} - -// AdjustExpiresByCredentialsCacheStrategy is an interface for CredentialCache -// to allow CredentialsProvider to intercept adjustments to Credentials expiry -// based on expectations and use cases of CredentialsProvider. -// -// Credential caches may use default implementation if nil. -type AdjustExpiresByCredentialsCacheStrategy interface { - // Given a Credentials as input, applying any mutations and - // returning the potentially updated Credentials, or error. - AdjustExpiresBy(Credentials, time.Duration) (Credentials, error) -} - -// defaultAdjustExpiresBy adds the duration to the passed in credentials Expires, -// and returns the updated credentials value. If Credentials value's CanExpire -// is false, the passed in credentials are returned unchanged. -func defaultAdjustExpiresBy(creds Credentials, dur time.Duration) (Credentials, error) { - if !creds.CanExpire { - return creds, nil - } - - creds.Expires = creds.Expires.Add(dur) - return creds, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go deleted file mode 100644 index 9f94cfe..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go +++ /dev/null @@ -1,234 +0,0 @@ -package aws - -import ( - "context" - "fmt" - "reflect" - "time" - - "github.com/aws/aws-sdk-go-v2/internal/sdk" -) - -// AnonymousCredentials provides a sentinel CredentialsProvider that should be -// used to instruct the SDK's signing middleware to not sign the request. -// -// Using `nil` credentials when configuring an API client will achieve the same -// result. The AnonymousCredentials type allows you to configure the SDK's -// external config loading to not attempt to source credentials from the shared -// config or environment. -// -// For example you can use this CredentialsProvider with an API client's -// Options to instruct the client not to sign a request for accessing public -// S3 bucket objects. -// -// The following example demonstrates using the AnonymousCredentials to prevent -// SDK's external config loading attempt to resolve credentials. -// -// cfg, err := config.LoadDefaultConfig(context.TODO(), -// config.WithCredentialsProvider(aws.AnonymousCredentials{}), -// ) -// if err != nil { -// log.Fatalf("failed to load config, %v", err) -// } -// -// client := s3.NewFromConfig(cfg) -// -// Alternatively you can leave the API client Option's `Credential` member to -// nil. If using the `NewFromConfig` constructor you'll need to explicitly set -// the `Credentials` member to nil, if the external config resolved a -// credential provider. -// -// client := s3.New(s3.Options{ -// // Credentials defaults to a nil value. -// }) -// -// This can also be configured for specific operations calls too. -// -// cfg, err := config.LoadDefaultConfig(context.TODO()) -// if err != nil { -// log.Fatalf("failed to load config, %v", err) -// } -// -// client := s3.NewFromConfig(config) -// -// result, err := client.GetObject(context.TODO(), s3.GetObject{ -// Bucket: aws.String("example-bucket"), -// Key: aws.String("example-key"), -// }, func(o *s3.Options) { -// o.Credentials = nil -// // Or -// o.Credentials = aws.AnonymousCredentials{} -// }) -type AnonymousCredentials struct{} - -// Retrieve implements the CredentialsProvider interface, but will always -// return error, and cannot be used to sign a request. The AnonymousCredentials -// type is used as a sentinel type instructing the AWS request signing -// middleware to not sign a request. -func (AnonymousCredentials) Retrieve(context.Context) (Credentials, error) { - return Credentials{Source: "AnonymousCredentials"}, - fmt.Errorf("the AnonymousCredentials is not a valid credential provider, and cannot be used to sign AWS requests with") -} - -// CredentialSource is the source of the credential provider. -// A provider can have multiple credential sources: For example, a provider that reads a profile, calls ECS to -// get credentials and then assumes a role using STS will have all these as part of its provider chain. -type CredentialSource int - -const ( - // CredentialSourceUndefined is the sentinel zero value - CredentialSourceUndefined CredentialSource = iota - // CredentialSourceCode credentials resolved from code, cli parameters, session object, or client instance - CredentialSourceCode - // CredentialSourceEnvVars credentials resolved from environment variables - CredentialSourceEnvVars - // CredentialSourceEnvVarsSTSWebIDToken credentials resolved from environment variables for assuming a role with STS using a web identity token - CredentialSourceEnvVarsSTSWebIDToken - // CredentialSourceSTSAssumeRole credentials resolved from STS using AssumeRole - CredentialSourceSTSAssumeRole - // CredentialSourceSTSAssumeRoleSaml credentials resolved from STS using assume role with SAML - CredentialSourceSTSAssumeRoleSaml - // CredentialSourceSTSAssumeRoleWebID credentials resolved from STS using assume role with web identity - CredentialSourceSTSAssumeRoleWebID - // CredentialSourceSTSFederationToken credentials resolved from STS using a federation token - CredentialSourceSTSFederationToken - // CredentialSourceSTSSessionToken credentials resolved from STS using a session token S - CredentialSourceSTSSessionToken - // CredentialSourceProfile credentials resolved from a config file(s) profile with static credentials - CredentialSourceProfile - // CredentialSourceProfileSourceProfile credentials resolved from a source profile in a config file(s) profile - CredentialSourceProfileSourceProfile - // CredentialSourceProfileNamedProvider credentials resolved from a named provider in a config file(s) profile (like EcsContainer) - CredentialSourceProfileNamedProvider - // CredentialSourceProfileSTSWebIDToken credentials resolved from configuration for assuming a role with STS using web identity token in a config file(s) profile - CredentialSourceProfileSTSWebIDToken - // CredentialSourceProfileSSO credentials resolved from an SSO session in a config file(s) profile - CredentialSourceProfileSSO - // CredentialSourceSSO credentials resolved from an SSO session - CredentialSourceSSO - // CredentialSourceProfileSSOLegacy credentials resolved from an SSO session in a config file(s) profile using legacy format - CredentialSourceProfileSSOLegacy - // CredentialSourceSSOLegacy credentials resolved from an SSO session using legacy format - CredentialSourceSSOLegacy - // CredentialSourceProfileProcess credentials resolved from a process in a config file(s) profile - CredentialSourceProfileProcess - // CredentialSourceProcess credentials resolved from a process - CredentialSourceProcess - // CredentialSourceHTTP credentials resolved from an HTTP endpoint - CredentialSourceHTTP - // CredentialSourceIMDS credentials resolved from the instance metadata service (IMDS) - CredentialSourceIMDS - // CredentialSourceProfileLogin credentials resolved from an `aws login` session sourced from a profile - CredentialSourceProfileLogin - // CredentialSourceLogin credentials resolved from an `aws login` session - CredentialSourceLogin -) - -// A Credentials is the AWS credentials value for individual credential fields. -type Credentials struct { - // AWS Access key ID - AccessKeyID string - - // AWS Secret Access Key - SecretAccessKey string - - // AWS Session Token - SessionToken string - - // Source of the credentials - Source string - - // States if the credentials can expire or not. - CanExpire bool - - // The time the credentials will expire at. Should be ignored if CanExpire - // is false. - Expires time.Time - - // The ID of the account for the credentials. - AccountID string -} - -// Expired returns if the credentials have expired. -func (v Credentials) Expired() bool { - if v.CanExpire { - // Calling Round(0) on the current time will truncate the monotonic - // reading only. Ensures credential expiry time is always based on - // reported wall-clock time. - return !v.Expires.After(sdk.NowTime().Round(0)) - } - - return false -} - -// HasKeys returns if the credentials keys are set. -func (v Credentials) HasKeys() bool { - return len(v.AccessKeyID) > 0 && len(v.SecretAccessKey) > 0 -} - -// A CredentialsProvider is the interface for any component which will provide -// credentials Credentials. A CredentialsProvider is required to manage its own -// Expired state, and what to be expired means. -// -// A credentials provider implementation can be wrapped with a CredentialCache -// to cache the credential value retrieved. Without the cache the SDK will -// attempt to retrieve the credentials for every request. -type CredentialsProvider interface { - // Retrieve returns nil if it successfully retrieved the value. - // Error is returned if the value were not obtainable, or empty. - Retrieve(ctx context.Context) (Credentials, error) -} - -// CredentialProviderSource allows any credential provider to track -// all providers where a credential provider were sourced. For example, if the credentials came from a -// call to a role specified in the profile, this method will give the whole breadcrumb trail -type CredentialProviderSource interface { - ProviderSources() []CredentialSource -} - -// CredentialsProviderFunc provides a helper wrapping a function value to -// satisfy the CredentialsProvider interface. -type CredentialsProviderFunc func(context.Context) (Credentials, error) - -// Retrieve delegates to the function value the CredentialsProviderFunc wraps. -func (fn CredentialsProviderFunc) Retrieve(ctx context.Context) (Credentials, error) { - return fn(ctx) -} - -type isCredentialsProvider interface { - IsCredentialsProvider(CredentialsProvider) bool -} - -// IsCredentialsProvider returns whether the target CredentialProvider is the same type as provider when comparing the -// implementation type. -// -// If provider has a method IsCredentialsProvider(CredentialsProvider) bool it will be responsible for validating -// whether target matches the credential provider type. -// -// When comparing the CredentialProvider implementations provider and target for equality, the following rules are used: -// -// If provider is of type T and target is of type V, true if type *T is the same as type *V, otherwise false -// If provider is of type *T and target is of type V, true if type *T is the same as type *V, otherwise false -// If provider is of type T and target is of type *V, true if type *T is the same as type *V, otherwise false -// If provider is of type *T and target is of type *V,true if type *T is the same as type *V, otherwise false -func IsCredentialsProvider(provider, target CredentialsProvider) bool { - if target == nil || provider == nil { - return provider == target - } - - if x, ok := provider.(isCredentialsProvider); ok { - return x.IsCredentialsProvider(target) - } - - targetType := reflect.TypeOf(target) - if targetType.Kind() != reflect.Ptr { - targetType = reflect.PtrTo(targetType) - } - - providerType := reflect.TypeOf(provider) - if providerType.Kind() != reflect.Ptr { - providerType = reflect.PtrTo(providerType) - } - - return targetType.AssignableTo(providerType) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/auto.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/auto.go deleted file mode 100644 index fd408e5..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/auto.go +++ /dev/null @@ -1,38 +0,0 @@ -package defaults - -import ( - "github.com/aws/aws-sdk-go-v2/aws" - "runtime" - "strings" -) - -var getGOOS = func() string { - return runtime.GOOS -} - -// ResolveDefaultsModeAuto is used to determine the effective aws.DefaultsMode when the mode -// is set to aws.DefaultsModeAuto. -func ResolveDefaultsModeAuto(region string, environment aws.RuntimeEnvironment) aws.DefaultsMode { - goos := getGOOS() - if goos == "android" || goos == "ios" { - return aws.DefaultsModeMobile - } - - var currentRegion string - if len(environment.EnvironmentIdentifier) > 0 { - currentRegion = environment.Region - } - - if len(currentRegion) == 0 && len(environment.EC2InstanceMetadataRegion) > 0 { - currentRegion = environment.EC2InstanceMetadataRegion - } - - if len(region) > 0 && len(currentRegion) > 0 { - if strings.EqualFold(region, currentRegion) { - return aws.DefaultsModeInRegion - } - return aws.DefaultsModeCrossRegion - } - - return aws.DefaultsModeStandard -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/configuration.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/configuration.go deleted file mode 100644 index 8b7e01f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/configuration.go +++ /dev/null @@ -1,43 +0,0 @@ -package defaults - -import ( - "time" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -// Configuration is the set of SDK configuration options that are determined based -// on the configured DefaultsMode. -type Configuration struct { - // RetryMode is the configuration's default retry mode API clients should - // use for constructing a Retryer. - RetryMode aws.RetryMode - - // ConnectTimeout is the maximum amount of time a dial will wait for - // a connect to complete. - // - // See https://pkg.go.dev/net#Dialer.Timeout - ConnectTimeout *time.Duration - - // TLSNegotiationTimeout specifies the maximum amount of time waiting to - // wait for a TLS handshake. - // - // See https://pkg.go.dev/net/http#Transport.TLSHandshakeTimeout - TLSNegotiationTimeout *time.Duration -} - -// GetConnectTimeout returns the ConnectTimeout value, returns false if the value is not set. -func (c *Configuration) GetConnectTimeout() (time.Duration, bool) { - if c.ConnectTimeout == nil { - return 0, false - } - return *c.ConnectTimeout, true -} - -// GetTLSNegotiationTimeout returns the TLSNegotiationTimeout value, returns false if the value is not set. -func (c *Configuration) GetTLSNegotiationTimeout() (time.Duration, bool) { - if c.TLSNegotiationTimeout == nil { - return 0, false - } - return *c.TLSNegotiationTimeout, true -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/defaults.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/defaults.go deleted file mode 100644 index dbaa873..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/defaults.go +++ /dev/null @@ -1,50 +0,0 @@ -// Code generated by github.com/aws/aws-sdk-go-v2/internal/codegen/cmd/defaultsconfig. DO NOT EDIT. - -package defaults - -import ( - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - "time" -) - -// GetModeConfiguration returns the default Configuration descriptor for the given mode. -// -// Supports the following modes: cross-region, in-region, mobile, standard -func GetModeConfiguration(mode aws.DefaultsMode) (Configuration, error) { - var mv aws.DefaultsMode - mv.SetFromString(string(mode)) - - switch mv { - case aws.DefaultsModeCrossRegion: - settings := Configuration{ - ConnectTimeout: aws.Duration(3100 * time.Millisecond), - RetryMode: aws.RetryMode("standard"), - TLSNegotiationTimeout: aws.Duration(3100 * time.Millisecond), - } - return settings, nil - case aws.DefaultsModeInRegion: - settings := Configuration{ - ConnectTimeout: aws.Duration(1100 * time.Millisecond), - RetryMode: aws.RetryMode("standard"), - TLSNegotiationTimeout: aws.Duration(1100 * time.Millisecond), - } - return settings, nil - case aws.DefaultsModeMobile: - settings := Configuration{ - ConnectTimeout: aws.Duration(30000 * time.Millisecond), - RetryMode: aws.RetryMode("standard"), - TLSNegotiationTimeout: aws.Duration(30000 * time.Millisecond), - } - return settings, nil - case aws.DefaultsModeStandard: - settings := Configuration{ - ConnectTimeout: aws.Duration(3100 * time.Millisecond), - RetryMode: aws.RetryMode("standard"), - TLSNegotiationTimeout: aws.Duration(3100 * time.Millisecond), - } - return settings, nil - default: - return Configuration{}, fmt.Errorf("unsupported defaults mode: %v", mode) - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/doc.go deleted file mode 100644 index 2d90011..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package defaults provides recommended configuration values for AWS SDKs and CLIs. -package defaults diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaultsmode.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/defaultsmode.go deleted file mode 100644 index fcf9387..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/defaultsmode.go +++ /dev/null @@ -1,95 +0,0 @@ -// Code generated by github.com/aws/aws-sdk-go-v2/internal/codegen/cmd/defaultsmode. DO NOT EDIT. - -package aws - -import ( - "strings" -) - -// DefaultsMode is the SDK defaults mode setting. -type DefaultsMode string - -// The DefaultsMode constants. -const ( - // DefaultsModeAuto is an experimental mode that builds on the standard mode. - // The SDK will attempt to discover the execution environment to determine the - // appropriate settings automatically. - // - // Note that the auto detection is heuristics-based and does not guarantee 100% - // accuracy. STANDARD mode will be used if the execution environment cannot - // be determined. The auto detection might query EC2 Instance Metadata service - // (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html), - // which might introduce latency. Therefore we recommend choosing an explicit - // defaults_mode instead if startup latency is critical to your application - DefaultsModeAuto DefaultsMode = "auto" - - // DefaultsModeCrossRegion builds on the standard mode and includes optimization - // tailored for applications which call AWS services in a different region - // - // Note that the default values vended from this mode might change as best practices - // may evolve. As a result, it is encouraged to perform tests when upgrading - // the SDK - DefaultsModeCrossRegion DefaultsMode = "cross-region" - - // DefaultsModeInRegion builds on the standard mode and includes optimization - // tailored for applications which call AWS services from within the same AWS - // region - // - // Note that the default values vended from this mode might change as best practices - // may evolve. As a result, it is encouraged to perform tests when upgrading - // the SDK - DefaultsModeInRegion DefaultsMode = "in-region" - - // DefaultsModeLegacy provides default settings that vary per SDK and were used - // prior to establishment of defaults_mode - DefaultsModeLegacy DefaultsMode = "legacy" - - // DefaultsModeMobile builds on the standard mode and includes optimization - // tailored for mobile applications - // - // Note that the default values vended from this mode might change as best practices - // may evolve. As a result, it is encouraged to perform tests when upgrading - // the SDK - DefaultsModeMobile DefaultsMode = "mobile" - - // DefaultsModeStandard provides the latest recommended default values that - // should be safe to run in most scenarios - // - // Note that the default values vended from this mode might change as best practices - // may evolve. As a result, it is encouraged to perform tests when upgrading - // the SDK - DefaultsModeStandard DefaultsMode = "standard" -) - -// SetFromString sets the DefaultsMode value to one of the pre-defined constants that matches -// the provided string when compared using EqualFold. If the value does not match a known -// constant it will be set to as-is and the function will return false. As a special case, if the -// provided value is a zero-length string, the mode will be set to LegacyDefaultsMode. -func (d *DefaultsMode) SetFromString(v string) (ok bool) { - switch { - case strings.EqualFold(v, string(DefaultsModeAuto)): - *d = DefaultsModeAuto - ok = true - case strings.EqualFold(v, string(DefaultsModeCrossRegion)): - *d = DefaultsModeCrossRegion - ok = true - case strings.EqualFold(v, string(DefaultsModeInRegion)): - *d = DefaultsModeInRegion - ok = true - case strings.EqualFold(v, string(DefaultsModeLegacy)): - *d = DefaultsModeLegacy - ok = true - case strings.EqualFold(v, string(DefaultsModeMobile)): - *d = DefaultsModeMobile - ok = true - case strings.EqualFold(v, string(DefaultsModeStandard)): - *d = DefaultsModeStandard - ok = true - case len(v) == 0: - *d = DefaultsModeLegacy - ok = true - default: - *d = DefaultsMode(v) - } - return ok -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/doc.go deleted file mode 100644 index d8b6e09..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/doc.go +++ /dev/null @@ -1,62 +0,0 @@ -// Package aws provides the core SDK's utilities and shared types. Use this package's -// utilities to simplify setting and reading API operations parameters. -// -// # Value and Pointer Conversion Utilities -// -// This package includes a helper conversion utility for each scalar type the SDK's -// API use. These utilities make getting a pointer of the scalar, and dereferencing -// a pointer easier. -// -// Each conversion utility comes in two forms. Value to Pointer and Pointer to Value. -// The Pointer to value will safely dereference the pointer and return its value. -// If the pointer was nil, the scalar's zero value will be returned. -// -// The value to pointer functions will be named after the scalar type. So get a -// *string from a string value use the "String" function. This makes it easy to -// to get pointer of a literal string value, because getting the address of a -// literal requires assigning the value to a variable first. -// -// var strPtr *string -// -// // Without the SDK's conversion functions -// str := "my string" -// strPtr = &str -// -// // With the SDK's conversion functions -// strPtr = aws.String("my string") -// -// // Convert *string to string value -// str = aws.ToString(strPtr) -// -// In addition to scalars the aws package also includes conversion utilities for -// map and slice for commonly types used in API parameters. The map and slice -// conversion functions use similar naming pattern as the scalar conversion -// functions. -// -// var strPtrs []*string -// var strs []string = []string{"Go", "Gophers", "Go"} -// -// // Convert []string to []*string -// strPtrs = aws.StringSlice(strs) -// -// // Convert []*string to []string -// strs = aws.ToStringSlice(strPtrs) -// -// # SDK Default HTTP Client -// -// The SDK will use the http.DefaultClient if a HTTP client is not provided to -// the SDK's Session, or service client constructor. This means that if the -// http.DefaultClient is modified by other components of your application the -// modifications will be picked up by the SDK as well. -// -// In some cases this might be intended, but it is a better practice to create -// a custom HTTP Client to share explicitly through your application. You can -// configure the SDK to use the custom HTTP Client by setting the HTTPClient -// value of the SDK's Config type when creating a Session or service client. -package aws - -// generate.go uses a build tag of "ignore", go run doesn't need to specify -// this because go run ignores all build flags when running a go file directly. -//go:generate go run -tags codegen generate.go -//go:generate go run -tags codegen logging_generate.go -//go:generate gofmt -w -s . diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints.go deleted file mode 100644 index 99edbf3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints.go +++ /dev/null @@ -1,247 +0,0 @@ -package aws - -import ( - "fmt" -) - -// DualStackEndpointState is a constant to describe the dual-stack endpoint resolution behavior. -type DualStackEndpointState uint - -const ( - // DualStackEndpointStateUnset is the default value behavior for dual-stack endpoint resolution. - DualStackEndpointStateUnset DualStackEndpointState = iota - - // DualStackEndpointStateEnabled enables dual-stack endpoint resolution for service endpoints. - DualStackEndpointStateEnabled - - // DualStackEndpointStateDisabled disables dual-stack endpoint resolution for endpoints. - DualStackEndpointStateDisabled -) - -// GetUseDualStackEndpoint takes a service's EndpointResolverOptions and returns the UseDualStackEndpoint value. -// Returns boolean false if the provided options does not have a method to retrieve the DualStackEndpointState. -func GetUseDualStackEndpoint(options ...interface{}) (value DualStackEndpointState, found bool) { - type iface interface { - GetUseDualStackEndpoint() DualStackEndpointState - } - for _, option := range options { - if i, ok := option.(iface); ok { - value = i.GetUseDualStackEndpoint() - found = true - break - } - } - return value, found -} - -// FIPSEndpointState is a constant to describe the FIPS endpoint resolution behavior. -type FIPSEndpointState uint - -const ( - // FIPSEndpointStateUnset is the default value behavior for FIPS endpoint resolution. - FIPSEndpointStateUnset FIPSEndpointState = iota - - // FIPSEndpointStateEnabled enables FIPS endpoint resolution for service endpoints. - FIPSEndpointStateEnabled - - // FIPSEndpointStateDisabled disables FIPS endpoint resolution for endpoints. - FIPSEndpointStateDisabled -) - -// GetUseFIPSEndpoint takes a service's EndpointResolverOptions and returns the UseDualStackEndpoint value. -// Returns boolean false if the provided options does not have a method to retrieve the DualStackEndpointState. -func GetUseFIPSEndpoint(options ...interface{}) (value FIPSEndpointState, found bool) { - type iface interface { - GetUseFIPSEndpoint() FIPSEndpointState - } - for _, option := range options { - if i, ok := option.(iface); ok { - value = i.GetUseFIPSEndpoint() - found = true - break - } - } - return value, found -} - -// Endpoint represents the endpoint a service client should make API operation -// calls to. -// -// The SDK will automatically resolve these endpoints per API client using an -// internal endpoint resolvers. If you'd like to provide custom endpoint -// resolving behavior you can implement the EndpointResolver interface. -// -// Deprecated: This structure was used with the global [EndpointResolver] -// interface, which has been deprecated in favor of service-specific endpoint -// resolution. See the deprecation docs on that interface for more information. -type Endpoint struct { - // The base URL endpoint the SDK API clients will use to make API calls to. - // The SDK will suffix URI path and query elements to this endpoint. - URL string - - // Specifies if the endpoint's hostname can be modified by the SDK's API - // client. - // - // If the hostname is mutable the SDK API clients may modify any part of - // the hostname based on the requirements of the API, (e.g. adding, or - // removing content in the hostname). Such as, Amazon S3 API client - // prefixing "bucketname" to the hostname, or changing the - // hostname service name component from "s3." to "s3-accesspoint.dualstack." - // for the dualstack endpoint of an S3 Accesspoint resource. - // - // Care should be taken when providing a custom endpoint for an API. If the - // endpoint hostname is mutable, and the client cannot modify the endpoint - // correctly, the operation call will most likely fail, or have undefined - // behavior. - // - // If hostname is immutable, the SDK API clients will not modify the - // hostname of the URL. This may cause the API client not to function - // correctly if the API requires the operation specific hostname values - // to be used by the client. - // - // This flag does not modify the API client's behavior if this endpoint - // will be used instead of Endpoint Discovery, or if the endpoint will be - // used to perform Endpoint Discovery. That behavior is configured via the - // API Client's Options. - HostnameImmutable bool - - // The AWS partition the endpoint belongs to. - PartitionID string - - // The service name that should be used for signing the requests to the - // endpoint. - SigningName string - - // The region that should be used for signing the request to the endpoint. - SigningRegion string - - // The signing method that should be used for signing the requests to the - // endpoint. - SigningMethod string - - // The source of the Endpoint. By default, this will be EndpointSourceServiceMetadata. - // When providing a custom endpoint, you should set the source as EndpointSourceCustom. - // If source is not provided when providing a custom endpoint, the SDK may not - // perform required host mutations correctly. Source should be used along with - // HostnameImmutable property as per the usage requirement. - Source EndpointSource -} - -// EndpointSource is the endpoint source type. -// -// Deprecated: The global [Endpoint] structure is deprecated. -type EndpointSource int - -const ( - // EndpointSourceServiceMetadata denotes service modeled endpoint metadata is used as Endpoint Source. - EndpointSourceServiceMetadata EndpointSource = iota - - // EndpointSourceCustom denotes endpoint is a custom endpoint. This source should be used when - // user provides a custom endpoint to be used by the SDK. - EndpointSourceCustom -) - -// EndpointNotFoundError is a sentinel error to indicate that the -// EndpointResolver implementation was unable to resolve an endpoint for the -// given service and region. Resolvers should use this to indicate that an API -// client should fallback and attempt to use it's internal default resolver to -// resolve the endpoint. -type EndpointNotFoundError struct { - Err error -} - -// Error is the error message. -func (e *EndpointNotFoundError) Error() string { - return fmt.Sprintf("endpoint not found, %v", e.Err) -} - -// Unwrap returns the underlying error. -func (e *EndpointNotFoundError) Unwrap() error { - return e.Err -} - -// EndpointResolver is an endpoint resolver that can be used to provide or -// override an endpoint for the given service and region. API clients will -// attempt to use the EndpointResolver first to resolve an endpoint if -// available. If the EndpointResolver returns an EndpointNotFoundError error, -// API clients will fallback to attempting to resolve the endpoint using its -// internal default endpoint resolver. -// -// Deprecated: The global endpoint resolution interface is deprecated. The API -// for endpoint resolution is now unique to each service and is set via the -// EndpointResolverV2 field on service client options. Setting a value for -// EndpointResolver on aws.Config or service client options will prevent you -// from using any endpoint-related service features released after the -// introduction of EndpointResolverV2. You may also encounter broken or -// unexpected behavior when using the old global interface with services that -// use many endpoint-related customizations such as S3. -type EndpointResolver interface { - ResolveEndpoint(service, region string) (Endpoint, error) -} - -// EndpointResolverFunc wraps a function to satisfy the EndpointResolver interface. -// -// Deprecated: The global endpoint resolution interface is deprecated. See -// deprecation docs on [EndpointResolver]. -type EndpointResolverFunc func(service, region string) (Endpoint, error) - -// ResolveEndpoint calls the wrapped function and returns the results. -func (e EndpointResolverFunc) ResolveEndpoint(service, region string) (Endpoint, error) { - return e(service, region) -} - -// EndpointResolverWithOptions is an endpoint resolver that can be used to provide or -// override an endpoint for the given service, region, and the service client's EndpointOptions. API clients will -// attempt to use the EndpointResolverWithOptions first to resolve an endpoint if -// available. If the EndpointResolverWithOptions returns an EndpointNotFoundError error, -// API clients will fallback to attempting to resolve the endpoint using its -// internal default endpoint resolver. -// -// Deprecated: The global endpoint resolution interface is deprecated. See -// deprecation docs on [EndpointResolver]. -type EndpointResolverWithOptions interface { - ResolveEndpoint(service, region string, options ...interface{}) (Endpoint, error) -} - -// EndpointResolverWithOptionsFunc wraps a function to satisfy the EndpointResolverWithOptions interface. -// -// Deprecated: The global endpoint resolution interface is deprecated. See -// deprecation docs on [EndpointResolver]. -type EndpointResolverWithOptionsFunc func(service, region string, options ...interface{}) (Endpoint, error) - -// ResolveEndpoint calls the wrapped function and returns the results. -func (e EndpointResolverWithOptionsFunc) ResolveEndpoint(service, region string, options ...interface{}) (Endpoint, error) { - return e(service, region, options...) -} - -// GetDisableHTTPS takes a service's EndpointResolverOptions and returns the DisableHTTPS value. -// Returns boolean false if the provided options does not have a method to retrieve the DisableHTTPS. -func GetDisableHTTPS(options ...interface{}) (value bool, found bool) { - type iface interface { - GetDisableHTTPS() bool - } - for _, option := range options { - if i, ok := option.(iface); ok { - value = i.GetDisableHTTPS() - found = true - break - } - } - return value, found -} - -// GetResolvedRegion takes a service's EndpointResolverOptions and returns the ResolvedRegion value. -// Returns boolean false if the provided options does not have a method to retrieve the ResolvedRegion. -func GetResolvedRegion(options ...interface{}) (value string, found bool) { - type iface interface { - GetResolvedRegion() string - } - for _, option := range options { - if i, ok := option.(iface); ok { - value = i.GetResolvedRegion() - found = true - break - } - } - return value, found -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/errors.go deleted file mode 100644 index f390a08..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/errors.go +++ /dev/null @@ -1,9 +0,0 @@ -package aws - -// MissingRegionError is an error that is returned if region configuration -// value was not found. -type MissingRegionError struct{} - -func (*MissingRegionError) Error() string { - return "an AWS region is required, but was not found" -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/from_ptr.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/from_ptr.go deleted file mode 100644 index 2394418..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/from_ptr.go +++ /dev/null @@ -1,365 +0,0 @@ -// Code generated by aws/generate.go DO NOT EDIT. - -package aws - -import ( - "github.com/aws/smithy-go/ptr" - "time" -) - -// ToBool returns bool value dereferenced if the passed -// in pointer was not nil. Returns a bool zero value if the -// pointer was nil. -func ToBool(p *bool) (v bool) { - return ptr.ToBool(p) -} - -// ToBoolSlice returns a slice of bool values, that are -// dereferenced if the passed in pointer was not nil. Returns a bool -// zero value if the pointer was nil. -func ToBoolSlice(vs []*bool) []bool { - return ptr.ToBoolSlice(vs) -} - -// ToBoolMap returns a map of bool values, that are -// dereferenced if the passed in pointer was not nil. The bool -// zero value is used if the pointer was nil. -func ToBoolMap(vs map[string]*bool) map[string]bool { - return ptr.ToBoolMap(vs) -} - -// ToByte returns byte value dereferenced if the passed -// in pointer was not nil. Returns a byte zero value if the -// pointer was nil. -func ToByte(p *byte) (v byte) { - return ptr.ToByte(p) -} - -// ToByteSlice returns a slice of byte values, that are -// dereferenced if the passed in pointer was not nil. Returns a byte -// zero value if the pointer was nil. -func ToByteSlice(vs []*byte) []byte { - return ptr.ToByteSlice(vs) -} - -// ToByteMap returns a map of byte values, that are -// dereferenced if the passed in pointer was not nil. The byte -// zero value is used if the pointer was nil. -func ToByteMap(vs map[string]*byte) map[string]byte { - return ptr.ToByteMap(vs) -} - -// ToString returns string value dereferenced if the passed -// in pointer was not nil. Returns a string zero value if the -// pointer was nil. -func ToString(p *string) (v string) { - return ptr.ToString(p) -} - -// ToStringSlice returns a slice of string values, that are -// dereferenced if the passed in pointer was not nil. Returns a string -// zero value if the pointer was nil. -func ToStringSlice(vs []*string) []string { - return ptr.ToStringSlice(vs) -} - -// ToStringMap returns a map of string values, that are -// dereferenced if the passed in pointer was not nil. The string -// zero value is used if the pointer was nil. -func ToStringMap(vs map[string]*string) map[string]string { - return ptr.ToStringMap(vs) -} - -// ToInt returns int value dereferenced if the passed -// in pointer was not nil. Returns a int zero value if the -// pointer was nil. -func ToInt(p *int) (v int) { - return ptr.ToInt(p) -} - -// ToIntSlice returns a slice of int values, that are -// dereferenced if the passed in pointer was not nil. Returns a int -// zero value if the pointer was nil. -func ToIntSlice(vs []*int) []int { - return ptr.ToIntSlice(vs) -} - -// ToIntMap returns a map of int values, that are -// dereferenced if the passed in pointer was not nil. The int -// zero value is used if the pointer was nil. -func ToIntMap(vs map[string]*int) map[string]int { - return ptr.ToIntMap(vs) -} - -// ToInt8 returns int8 value dereferenced if the passed -// in pointer was not nil. Returns a int8 zero value if the -// pointer was nil. -func ToInt8(p *int8) (v int8) { - return ptr.ToInt8(p) -} - -// ToInt8Slice returns a slice of int8 values, that are -// dereferenced if the passed in pointer was not nil. Returns a int8 -// zero value if the pointer was nil. -func ToInt8Slice(vs []*int8) []int8 { - return ptr.ToInt8Slice(vs) -} - -// ToInt8Map returns a map of int8 values, that are -// dereferenced if the passed in pointer was not nil. The int8 -// zero value is used if the pointer was nil. -func ToInt8Map(vs map[string]*int8) map[string]int8 { - return ptr.ToInt8Map(vs) -} - -// ToInt16 returns int16 value dereferenced if the passed -// in pointer was not nil. Returns a int16 zero value if the -// pointer was nil. -func ToInt16(p *int16) (v int16) { - return ptr.ToInt16(p) -} - -// ToInt16Slice returns a slice of int16 values, that are -// dereferenced if the passed in pointer was not nil. Returns a int16 -// zero value if the pointer was nil. -func ToInt16Slice(vs []*int16) []int16 { - return ptr.ToInt16Slice(vs) -} - -// ToInt16Map returns a map of int16 values, that are -// dereferenced if the passed in pointer was not nil. The int16 -// zero value is used if the pointer was nil. -func ToInt16Map(vs map[string]*int16) map[string]int16 { - return ptr.ToInt16Map(vs) -} - -// ToInt32 returns int32 value dereferenced if the passed -// in pointer was not nil. Returns a int32 zero value if the -// pointer was nil. -func ToInt32(p *int32) (v int32) { - return ptr.ToInt32(p) -} - -// ToInt32Slice returns a slice of int32 values, that are -// dereferenced if the passed in pointer was not nil. Returns a int32 -// zero value if the pointer was nil. -func ToInt32Slice(vs []*int32) []int32 { - return ptr.ToInt32Slice(vs) -} - -// ToInt32Map returns a map of int32 values, that are -// dereferenced if the passed in pointer was not nil. The int32 -// zero value is used if the pointer was nil. -func ToInt32Map(vs map[string]*int32) map[string]int32 { - return ptr.ToInt32Map(vs) -} - -// ToInt64 returns int64 value dereferenced if the passed -// in pointer was not nil. Returns a int64 zero value if the -// pointer was nil. -func ToInt64(p *int64) (v int64) { - return ptr.ToInt64(p) -} - -// ToInt64Slice returns a slice of int64 values, that are -// dereferenced if the passed in pointer was not nil. Returns a int64 -// zero value if the pointer was nil. -func ToInt64Slice(vs []*int64) []int64 { - return ptr.ToInt64Slice(vs) -} - -// ToInt64Map returns a map of int64 values, that are -// dereferenced if the passed in pointer was not nil. The int64 -// zero value is used if the pointer was nil. -func ToInt64Map(vs map[string]*int64) map[string]int64 { - return ptr.ToInt64Map(vs) -} - -// ToUint returns uint value dereferenced if the passed -// in pointer was not nil. Returns a uint zero value if the -// pointer was nil. -func ToUint(p *uint) (v uint) { - return ptr.ToUint(p) -} - -// ToUintSlice returns a slice of uint values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint -// zero value if the pointer was nil. -func ToUintSlice(vs []*uint) []uint { - return ptr.ToUintSlice(vs) -} - -// ToUintMap returns a map of uint values, that are -// dereferenced if the passed in pointer was not nil. The uint -// zero value is used if the pointer was nil. -func ToUintMap(vs map[string]*uint) map[string]uint { - return ptr.ToUintMap(vs) -} - -// ToUint8 returns uint8 value dereferenced if the passed -// in pointer was not nil. Returns a uint8 zero value if the -// pointer was nil. -func ToUint8(p *uint8) (v uint8) { - return ptr.ToUint8(p) -} - -// ToUint8Slice returns a slice of uint8 values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint8 -// zero value if the pointer was nil. -func ToUint8Slice(vs []*uint8) []uint8 { - return ptr.ToUint8Slice(vs) -} - -// ToUint8Map returns a map of uint8 values, that are -// dereferenced if the passed in pointer was not nil. The uint8 -// zero value is used if the pointer was nil. -func ToUint8Map(vs map[string]*uint8) map[string]uint8 { - return ptr.ToUint8Map(vs) -} - -// ToUint16 returns uint16 value dereferenced if the passed -// in pointer was not nil. Returns a uint16 zero value if the -// pointer was nil. -func ToUint16(p *uint16) (v uint16) { - return ptr.ToUint16(p) -} - -// ToUint16Slice returns a slice of uint16 values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint16 -// zero value if the pointer was nil. -func ToUint16Slice(vs []*uint16) []uint16 { - return ptr.ToUint16Slice(vs) -} - -// ToUint16Map returns a map of uint16 values, that are -// dereferenced if the passed in pointer was not nil. The uint16 -// zero value is used if the pointer was nil. -func ToUint16Map(vs map[string]*uint16) map[string]uint16 { - return ptr.ToUint16Map(vs) -} - -// ToUint32 returns uint32 value dereferenced if the passed -// in pointer was not nil. Returns a uint32 zero value if the -// pointer was nil. -func ToUint32(p *uint32) (v uint32) { - return ptr.ToUint32(p) -} - -// ToUint32Slice returns a slice of uint32 values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint32 -// zero value if the pointer was nil. -func ToUint32Slice(vs []*uint32) []uint32 { - return ptr.ToUint32Slice(vs) -} - -// ToUint32Map returns a map of uint32 values, that are -// dereferenced if the passed in pointer was not nil. The uint32 -// zero value is used if the pointer was nil. -func ToUint32Map(vs map[string]*uint32) map[string]uint32 { - return ptr.ToUint32Map(vs) -} - -// ToUint64 returns uint64 value dereferenced if the passed -// in pointer was not nil. Returns a uint64 zero value if the -// pointer was nil. -func ToUint64(p *uint64) (v uint64) { - return ptr.ToUint64(p) -} - -// ToUint64Slice returns a slice of uint64 values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint64 -// zero value if the pointer was nil. -func ToUint64Slice(vs []*uint64) []uint64 { - return ptr.ToUint64Slice(vs) -} - -// ToUint64Map returns a map of uint64 values, that are -// dereferenced if the passed in pointer was not nil. The uint64 -// zero value is used if the pointer was nil. -func ToUint64Map(vs map[string]*uint64) map[string]uint64 { - return ptr.ToUint64Map(vs) -} - -// ToFloat32 returns float32 value dereferenced if the passed -// in pointer was not nil. Returns a float32 zero value if the -// pointer was nil. -func ToFloat32(p *float32) (v float32) { - return ptr.ToFloat32(p) -} - -// ToFloat32Slice returns a slice of float32 values, that are -// dereferenced if the passed in pointer was not nil. Returns a float32 -// zero value if the pointer was nil. -func ToFloat32Slice(vs []*float32) []float32 { - return ptr.ToFloat32Slice(vs) -} - -// ToFloat32Map returns a map of float32 values, that are -// dereferenced if the passed in pointer was not nil. The float32 -// zero value is used if the pointer was nil. -func ToFloat32Map(vs map[string]*float32) map[string]float32 { - return ptr.ToFloat32Map(vs) -} - -// ToFloat64 returns float64 value dereferenced if the passed -// in pointer was not nil. Returns a float64 zero value if the -// pointer was nil. -func ToFloat64(p *float64) (v float64) { - return ptr.ToFloat64(p) -} - -// ToFloat64Slice returns a slice of float64 values, that are -// dereferenced if the passed in pointer was not nil. Returns a float64 -// zero value if the pointer was nil. -func ToFloat64Slice(vs []*float64) []float64 { - return ptr.ToFloat64Slice(vs) -} - -// ToFloat64Map returns a map of float64 values, that are -// dereferenced if the passed in pointer was not nil. The float64 -// zero value is used if the pointer was nil. -func ToFloat64Map(vs map[string]*float64) map[string]float64 { - return ptr.ToFloat64Map(vs) -} - -// ToTime returns time.Time value dereferenced if the passed -// in pointer was not nil. Returns a time.Time zero value if the -// pointer was nil. -func ToTime(p *time.Time) (v time.Time) { - return ptr.ToTime(p) -} - -// ToTimeSlice returns a slice of time.Time values, that are -// dereferenced if the passed in pointer was not nil. Returns a time.Time -// zero value if the pointer was nil. -func ToTimeSlice(vs []*time.Time) []time.Time { - return ptr.ToTimeSlice(vs) -} - -// ToTimeMap returns a map of time.Time values, that are -// dereferenced if the passed in pointer was not nil. The time.Time -// zero value is used if the pointer was nil. -func ToTimeMap(vs map[string]*time.Time) map[string]time.Time { - return ptr.ToTimeMap(vs) -} - -// ToDuration returns time.Duration value dereferenced if the passed -// in pointer was not nil. Returns a time.Duration zero value if the -// pointer was nil. -func ToDuration(p *time.Duration) (v time.Duration) { - return ptr.ToDuration(p) -} - -// ToDurationSlice returns a slice of time.Duration values, that are -// dereferenced if the passed in pointer was not nil. Returns a time.Duration -// zero value if the pointer was nil. -func ToDurationSlice(vs []*time.Duration) []time.Duration { - return ptr.ToDurationSlice(vs) -} - -// ToDurationMap returns a map of time.Duration values, that are -// dereferenced if the passed in pointer was not nil. The time.Duration -// zero value is used if the pointer was nil. -func ToDurationMap(vs map[string]*time.Duration) map[string]time.Duration { - return ptr.ToDurationMap(vs) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go deleted file mode 100644 index c9d0bdc..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package aws - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.41.0" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/logging.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/logging.go deleted file mode 100644 index 91c94d9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/logging.go +++ /dev/null @@ -1,119 +0,0 @@ -// Code generated by aws/logging_generate.go DO NOT EDIT. - -package aws - -// ClientLogMode represents the logging mode of SDK clients. The client logging mode is a bit-field where -// each bit is a flag that describes the logging behavior for one or more client components. -// The entire 64-bit group is reserved for later expansion by the SDK. -// -// Example: Setting ClientLogMode to enable logging of retries and requests -// -// clientLogMode := aws.LogRetries | aws.LogRequest -// -// Example: Adding an additional log mode to an existing ClientLogMode value -// -// clientLogMode |= aws.LogResponse -type ClientLogMode uint64 - -// Supported ClientLogMode bits that can be configured to toggle logging of specific SDK events. -const ( - LogSigning ClientLogMode = 1 << (64 - 1 - iota) - LogRetries - LogRequest - LogRequestWithBody - LogResponse - LogResponseWithBody - LogDeprecatedUsage - LogRequestEventMessage - LogResponseEventMessage -) - -// IsSigning returns whether the Signing logging mode bit is set -func (m ClientLogMode) IsSigning() bool { - return m&LogSigning != 0 -} - -// IsRetries returns whether the Retries logging mode bit is set -func (m ClientLogMode) IsRetries() bool { - return m&LogRetries != 0 -} - -// IsRequest returns whether the Request logging mode bit is set -func (m ClientLogMode) IsRequest() bool { - return m&LogRequest != 0 -} - -// IsRequestWithBody returns whether the RequestWithBody logging mode bit is set -func (m ClientLogMode) IsRequestWithBody() bool { - return m&LogRequestWithBody != 0 -} - -// IsResponse returns whether the Response logging mode bit is set -func (m ClientLogMode) IsResponse() bool { - return m&LogResponse != 0 -} - -// IsResponseWithBody returns whether the ResponseWithBody logging mode bit is set -func (m ClientLogMode) IsResponseWithBody() bool { - return m&LogResponseWithBody != 0 -} - -// IsDeprecatedUsage returns whether the DeprecatedUsage logging mode bit is set -func (m ClientLogMode) IsDeprecatedUsage() bool { - return m&LogDeprecatedUsage != 0 -} - -// IsRequestEventMessage returns whether the RequestEventMessage logging mode bit is set -func (m ClientLogMode) IsRequestEventMessage() bool { - return m&LogRequestEventMessage != 0 -} - -// IsResponseEventMessage returns whether the ResponseEventMessage logging mode bit is set -func (m ClientLogMode) IsResponseEventMessage() bool { - return m&LogResponseEventMessage != 0 -} - -// ClearSigning clears the Signing logging mode bit -func (m *ClientLogMode) ClearSigning() { - *m &^= LogSigning -} - -// ClearRetries clears the Retries logging mode bit -func (m *ClientLogMode) ClearRetries() { - *m &^= LogRetries -} - -// ClearRequest clears the Request logging mode bit -func (m *ClientLogMode) ClearRequest() { - *m &^= LogRequest -} - -// ClearRequestWithBody clears the RequestWithBody logging mode bit -func (m *ClientLogMode) ClearRequestWithBody() { - *m &^= LogRequestWithBody -} - -// ClearResponse clears the Response logging mode bit -func (m *ClientLogMode) ClearResponse() { - *m &^= LogResponse -} - -// ClearResponseWithBody clears the ResponseWithBody logging mode bit -func (m *ClientLogMode) ClearResponseWithBody() { - *m &^= LogResponseWithBody -} - -// ClearDeprecatedUsage clears the DeprecatedUsage logging mode bit -func (m *ClientLogMode) ClearDeprecatedUsage() { - *m &^= LogDeprecatedUsage -} - -// ClearRequestEventMessage clears the RequestEventMessage logging mode bit -func (m *ClientLogMode) ClearRequestEventMessage() { - *m &^= LogRequestEventMessage -} - -// ClearResponseEventMessage clears the ResponseEventMessage logging mode bit -func (m *ClientLogMode) ClearResponseEventMessage() { - *m &^= LogResponseEventMessage -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/logging_generate.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/logging_generate.go deleted file mode 100644 index 6ecc223..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/logging_generate.go +++ /dev/null @@ -1,95 +0,0 @@ -//go:build clientlogmode -// +build clientlogmode - -package main - -import ( - "fmt" - "log" - "os" - "strings" - "text/template" -) - -var config = struct { - ModeBits []string -}{ - // Items should be appended only to keep bit-flag positions stable - ModeBits: []string{ - "Signing", - "Retries", - "Request", - "RequestWithBody", - "Response", - "ResponseWithBody", - "DeprecatedUsage", - "RequestEventMessage", - "ResponseEventMessage", - }, -} - -func bitName(name string) string { - return strings.ToUpper(name[:1]) + name[1:] -} - -var tmpl = template.Must(template.New("ClientLogMode").Funcs(map[string]interface{}{ - "symbolName": func(name string) string { - return "Log" + bitName(name) - }, - "bitName": bitName, -}).Parse(`// Code generated by aws/logging_generate.go DO NOT EDIT. - -package aws - -// ClientLogMode represents the logging mode of SDK clients. The client logging mode is a bit-field where -// each bit is a flag that describes the logging behavior for one or more client components. -// The entire 64-bit group is reserved for later expansion by the SDK. -// -// Example: Setting ClientLogMode to enable logging of retries and requests -// clientLogMode := aws.LogRetries | aws.LogRequest -// -// Example: Adding an additional log mode to an existing ClientLogMode value -// clientLogMode |= aws.LogResponse -type ClientLogMode uint64 - -// Supported ClientLogMode bits that can be configured to toggle logging of specific SDK events. -const ( -{{- range $index, $field := .ModeBits }} - {{ (symbolName $field) }}{{- if (eq 0 $index) }} ClientLogMode = 1 << (64 - 1 - iota){{- end }} -{{- end }} -) -{{ range $_, $field := .ModeBits }} -// Is{{- bitName $field }} returns whether the {{ bitName $field }} logging mode bit is set -func (m ClientLogMode) Is{{- bitName $field }}() bool { - return m&{{- (symbolName $field) }} != 0 -} -{{ end }} -{{- range $_, $field := .ModeBits }} -// Clear{{- bitName $field }} clears the {{ bitName $field }} logging mode bit -func (m *ClientLogMode) Clear{{- bitName $field }}() { - *m &^= {{ (symbolName $field) }} -} -{{ end -}} -`)) - -func main() { - uniqueBitFields := make(map[string]struct{}) - - for _, bitName := range config.ModeBits { - if _, ok := uniqueBitFields[strings.ToLower(bitName)]; ok { - panic(fmt.Sprintf("duplicate bit field: %s", bitName)) - } - uniqueBitFields[bitName] = struct{}{} - } - - file, err := os.Create("logging.go") - if err != nil { - log.Fatal(err) - } - defer file.Close() - - err = tmpl.Execute(file, config) - if err != nil { - log.Fatal(err) - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/metadata.go deleted file mode 100644 index d66f096..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/metadata.go +++ /dev/null @@ -1,213 +0,0 @@ -package middleware - -import ( - "context" - - "github.com/aws/aws-sdk-go-v2/aws" - - "github.com/aws/smithy-go/middleware" -) - -// RegisterServiceMetadata registers metadata about the service and operation into the middleware context -// so that it is available at runtime for other middleware to introspect. -type RegisterServiceMetadata struct { - ServiceID string - SigningName string - Region string - OperationName string -} - -// ID returns the middleware identifier. -func (s *RegisterServiceMetadata) ID() string { - return "RegisterServiceMetadata" -} - -// HandleInitialize registers service metadata information into the middleware context, allowing for introspection. -func (s RegisterServiceMetadata) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) (out middleware.InitializeOutput, metadata middleware.Metadata, err error) { - if len(s.ServiceID) > 0 { - ctx = SetServiceID(ctx, s.ServiceID) - } - if len(s.SigningName) > 0 { - ctx = SetSigningName(ctx, s.SigningName) - } - if len(s.Region) > 0 { - ctx = setRegion(ctx, s.Region) - } - if len(s.OperationName) > 0 { - ctx = setOperationName(ctx, s.OperationName) - } - return next.HandleInitialize(ctx, in) -} - -// service metadata keys for storing and lookup of runtime stack information. -type ( - serviceIDKey struct{} - signingNameKey struct{} - signingRegionKey struct{} - regionKey struct{} - operationNameKey struct{} - partitionIDKey struct{} - requiresLegacyEndpointsKey struct{} -) - -// GetServiceID retrieves the service id from the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func GetServiceID(ctx context.Context) (v string) { - v, _ = middleware.GetStackValue(ctx, serviceIDKey{}).(string) - return v -} - -// GetSigningName retrieves the service signing name from the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -// -// Deprecated: This value is unstable. The resolved signing name is available -// in the signer properties object passed to the signer. -func GetSigningName(ctx context.Context) (v string) { - v, _ = middleware.GetStackValue(ctx, signingNameKey{}).(string) - return v -} - -// GetSigningRegion retrieves the region from the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -// -// Deprecated: This value is unstable. The resolved signing region is available -// in the signer properties object passed to the signer. -func GetSigningRegion(ctx context.Context) (v string) { - v, _ = middleware.GetStackValue(ctx, signingRegionKey{}).(string) - return v -} - -// GetRegion retrieves the endpoint region from the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func GetRegion(ctx context.Context) (v string) { - v, _ = middleware.GetStackValue(ctx, regionKey{}).(string) - return v -} - -// GetOperationName retrieves the service operation metadata from the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func GetOperationName(ctx context.Context) (v string) { - v, _ = middleware.GetStackValue(ctx, operationNameKey{}).(string) - return v -} - -// GetPartitionID retrieves the endpoint partition id from the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func GetPartitionID(ctx context.Context) string { - v, _ := middleware.GetStackValue(ctx, partitionIDKey{}).(string) - return v -} - -// GetRequiresLegacyEndpoints the flag used to indicate if legacy endpoint -// customizations need to be executed. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func GetRequiresLegacyEndpoints(ctx context.Context) bool { - v, _ := middleware.GetStackValue(ctx, requiresLegacyEndpointsKey{}).(bool) - return v -} - -// SetRequiresLegacyEndpoints set or modifies the flag indicated that -// legacy endpoint customizations are needed. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func SetRequiresLegacyEndpoints(ctx context.Context, value bool) context.Context { - return middleware.WithStackValue(ctx, requiresLegacyEndpointsKey{}, value) -} - -// SetSigningName set or modifies the sigv4 or sigv4a signing name on the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -// -// Deprecated: This value is unstable. Use WithSigV4SigningName client option -// funcs instead. -func SetSigningName(ctx context.Context, value string) context.Context { - return middleware.WithStackValue(ctx, signingNameKey{}, value) -} - -// SetSigningRegion sets or modifies the region on the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -// -// Deprecated: This value is unstable. Use WithSigV4SigningRegion client option -// funcs instead. -func SetSigningRegion(ctx context.Context, value string) context.Context { - return middleware.WithStackValue(ctx, signingRegionKey{}, value) -} - -// SetServiceID sets the service id on the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func SetServiceID(ctx context.Context, value string) context.Context { - return middleware.WithStackValue(ctx, serviceIDKey{}, value) -} - -// setRegion sets the endpoint region on the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func setRegion(ctx context.Context, value string) context.Context { - return middleware.WithStackValue(ctx, regionKey{}, value) -} - -// setOperationName sets the service operation on the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func setOperationName(ctx context.Context, value string) context.Context { - return middleware.WithStackValue(ctx, operationNameKey{}, value) -} - -// SetPartitionID sets the partition id of a resolved region on the context -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func SetPartitionID(ctx context.Context, value string) context.Context { - return middleware.WithStackValue(ctx, partitionIDKey{}, value) -} - -// EndpointSource key -type endpointSourceKey struct{} - -// GetEndpointSource returns an endpoint source if set on context -func GetEndpointSource(ctx context.Context) (v aws.EndpointSource) { - v, _ = middleware.GetStackValue(ctx, endpointSourceKey{}).(aws.EndpointSource) - return v -} - -// SetEndpointSource sets endpoint source on context -func SetEndpointSource(ctx context.Context, value aws.EndpointSource) context.Context { - return middleware.WithStackValue(ctx, endpointSourceKey{}, value) -} - -type signingCredentialsKey struct{} - -// GetSigningCredentials returns the credentials that were used for signing if set on context. -func GetSigningCredentials(ctx context.Context) (v aws.Credentials) { - v, _ = middleware.GetStackValue(ctx, signingCredentialsKey{}).(aws.Credentials) - return v -} - -// SetSigningCredentials sets the credentails used for signing on the context. -func SetSigningCredentials(ctx context.Context, value aws.Credentials) context.Context { - return middleware.WithStackValue(ctx, signingCredentialsKey{}, value) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/middleware.go deleted file mode 100644 index 6d5f007..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/middleware.go +++ /dev/null @@ -1,168 +0,0 @@ -package middleware - -import ( - "context" - "fmt" - "time" - - "github.com/aws/aws-sdk-go-v2/internal/rand" - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" - smithyrand "github.com/aws/smithy-go/rand" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// ClientRequestID is a Smithy BuildMiddleware that will generate a unique ID for logical API operation -// invocation. -type ClientRequestID struct{} - -// ID the identifier for the ClientRequestID -func (r *ClientRequestID) ID() string { - return "ClientRequestID" -} - -// HandleBuild attaches a unique operation invocation id for the operation to the request -func (r ClientRequestID) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", req) - } - - invocationID, err := smithyrand.NewUUID(rand.Reader).GetUUID() - if err != nil { - return out, metadata, err - } - - const invocationIDHeader = "Amz-Sdk-Invocation-Id" - req.Header[invocationIDHeader] = append(req.Header[invocationIDHeader][:0], invocationID) - - return next.HandleBuild(ctx, in) -} - -// RecordResponseTiming records the response timing for the SDK client requests. -type RecordResponseTiming struct{} - -// ID is the middleware identifier -func (a *RecordResponseTiming) ID() string { - return "RecordResponseTiming" -} - -// HandleDeserialize calculates response metadata and clock skew -func (a RecordResponseTiming) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - responseAt := sdk.NowTime() - setResponseAt(&metadata, responseAt) - - var serverTime time.Time - - switch resp := out.RawResponse.(type) { - case *smithyhttp.Response: - respDateHeader := resp.Header.Get("Date") - if len(respDateHeader) == 0 { - break - } - var parseErr error - serverTime, parseErr = smithyhttp.ParseTime(respDateHeader) - if parseErr != nil { - logger := middleware.GetLogger(ctx) - logger.Logf(logging.Warn, "failed to parse response Date header value, got %v", - parseErr.Error()) - break - } - setServerTime(&metadata, serverTime) - } - - if !serverTime.IsZero() { - attemptSkew := serverTime.Sub(responseAt) - setAttemptSkew(&metadata, attemptSkew) - } - - return out, metadata, err -} - -type responseAtKey struct{} - -// GetResponseAt returns the time response was received at. -func GetResponseAt(metadata middleware.Metadata) (v time.Time, ok bool) { - v, ok = metadata.Get(responseAtKey{}).(time.Time) - return v, ok -} - -// setResponseAt sets the response time on the metadata. -func setResponseAt(metadata *middleware.Metadata, v time.Time) { - metadata.Set(responseAtKey{}, v) -} - -type serverTimeKey struct{} - -// GetServerTime returns the server time for response. -func GetServerTime(metadata middleware.Metadata) (v time.Time, ok bool) { - v, ok = metadata.Get(serverTimeKey{}).(time.Time) - return v, ok -} - -// setServerTime sets the server time on the metadata. -func setServerTime(metadata *middleware.Metadata, v time.Time) { - metadata.Set(serverTimeKey{}, v) -} - -type attemptSkewKey struct{} - -// GetAttemptSkew returns Attempt clock skew for response from metadata. -func GetAttemptSkew(metadata middleware.Metadata) (v time.Duration, ok bool) { - v, ok = metadata.Get(attemptSkewKey{}).(time.Duration) - return v, ok -} - -// setAttemptSkew sets the attempt clock skew on the metadata. -func setAttemptSkew(metadata *middleware.Metadata, v time.Duration) { - metadata.Set(attemptSkewKey{}, v) -} - -// AddClientRequestIDMiddleware adds ClientRequestID to the middleware stack -func AddClientRequestIDMiddleware(stack *middleware.Stack) error { - return stack.Build.Add(&ClientRequestID{}, middleware.After) -} - -// AddRecordResponseTiming adds RecordResponseTiming middleware to the -// middleware stack. -func AddRecordResponseTiming(stack *middleware.Stack) error { - return stack.Deserialize.Add(&RecordResponseTiming{}, middleware.After) -} - -// rawResponseKey is the accessor key used to store and access the -// raw response within the response metadata. -type rawResponseKey struct{} - -// AddRawResponse middleware adds raw response on to the metadata -type AddRawResponse struct{} - -// ID the identifier for the ClientRequestID -func (m *AddRawResponse) ID() string { - return "AddRawResponseToMetadata" -} - -// HandleDeserialize adds raw response on the middleware metadata -func (m AddRawResponse) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - metadata.Set(rawResponseKey{}, out.RawResponse) - return out, metadata, err -} - -// AddRawResponseToMetadata adds middleware to the middleware stack that -// store raw response on to the metadata. -func AddRawResponseToMetadata(stack *middleware.Stack) error { - return stack.Deserialize.Add(&AddRawResponse{}, middleware.Before) -} - -// GetRawResponse returns raw response set on metadata -func GetRawResponse(metadata middleware.Metadata) interface{} { - return metadata.Get(rawResponseKey{}) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/osname.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/osname.go deleted file mode 100644 index ba262da..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/osname.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:build go1.16 -// +build go1.16 - -package middleware - -import "runtime" - -func getNormalizedOSName() (os string) { - switch runtime.GOOS { - case "android": - os = "android" - case "linux": - os = "linux" - case "windows": - os = "windows" - case "darwin": - os = "macos" - case "ios": - os = "ios" - default: - os = "other" - } - return os -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/osname_go115.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/osname_go115.go deleted file mode 100644 index e14a1e4..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/osname_go115.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:build !go1.16 -// +build !go1.16 - -package middleware - -import "runtime" - -func getNormalizedOSName() (os string) { - switch runtime.GOOS { - case "android": - os = "android" - case "linux": - os = "linux" - case "windows": - os = "windows" - case "darwin": - // Due to Apple M1 we can't distinguish between macOS and iOS when GOOS/GOARCH is darwin/amd64 - // For now declare this as "other" until we have a better detection mechanism. - fallthrough - default: - os = "other" - } - return os -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/recursion_detection.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/recursion_detection.go deleted file mode 100644 index 3f6aaf2..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/recursion_detection.go +++ /dev/null @@ -1,94 +0,0 @@ -package middleware - -import ( - "context" - "fmt" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "os" -) - -const envAwsLambdaFunctionName = "AWS_LAMBDA_FUNCTION_NAME" -const envAmznTraceID = "_X_AMZN_TRACE_ID" -const amznTraceIDHeader = "X-Amzn-Trace-Id" - -// AddRecursionDetection adds recursionDetection to the middleware stack -func AddRecursionDetection(stack *middleware.Stack) error { - return stack.Build.Add(&RecursionDetection{}, middleware.After) -} - -// RecursionDetection detects Lambda environment and sets its X-Ray trace ID to request header if absent -// to avoid recursion invocation in Lambda -type RecursionDetection struct{} - -// ID returns the middleware identifier -func (m *RecursionDetection) ID() string { - return "RecursionDetection" -} - -// HandleBuild detects Lambda environment and adds its trace ID to request header if absent -func (m *RecursionDetection) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown request type %T", req) - } - - _, hasLambdaEnv := os.LookupEnv(envAwsLambdaFunctionName) - xAmznTraceID, hasTraceID := os.LookupEnv(envAmznTraceID) - value := req.Header.Get(amznTraceIDHeader) - // only set the X-Amzn-Trace-Id header when it is not set initially, the - // current environment is Lambda and the _X_AMZN_TRACE_ID env variable exists - if value != "" || !hasLambdaEnv || !hasTraceID { - return next.HandleBuild(ctx, in) - } - - req.Header.Set(amznTraceIDHeader, percentEncode(xAmznTraceID)) - return next.HandleBuild(ctx, in) -} - -func percentEncode(s string) string { - upperhex := "0123456789ABCDEF" - hexCount := 0 - for i := 0; i < len(s); i++ { - c := s[i] - if shouldEncode(c) { - hexCount++ - } - } - - if hexCount == 0 { - return s - } - - required := len(s) + 2*hexCount - t := make([]byte, required) - j := 0 - for i := 0; i < len(s); i++ { - if c := s[i]; shouldEncode(c) { - t[j] = '%' - t[j+1] = upperhex[c>>4] - t[j+2] = upperhex[c&15] - j += 3 - } else { - t[j] = c - j++ - } - } - return string(t) -} - -func shouldEncode(c byte) bool { - if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' { - return false - } - switch c { - case '-', '=', ';', ':', '+', '&', '[', ']', '{', '}', '"', '\'', ',': - return false - default: - return true - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/request_id.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/request_id.go deleted file mode 100644 index dd3391f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/request_id.go +++ /dev/null @@ -1,27 +0,0 @@ -package middleware - -import ( - "github.com/aws/smithy-go/middleware" -) - -// requestIDKey is used to retrieve request id from response metadata -type requestIDKey struct{} - -// SetRequestIDMetadata sets the provided request id over middleware metadata -func SetRequestIDMetadata(metadata *middleware.Metadata, id string) { - metadata.Set(requestIDKey{}, id) -} - -// GetRequestIDMetadata retrieves the request id from middleware metadata -// returns string and bool indicating value of request id, whether request id was set. -func GetRequestIDMetadata(metadata middleware.Metadata) (string, bool) { - if !metadata.Has(requestIDKey{}) { - return "", false - } - - v, ok := metadata.Get(requestIDKey{}).(string) - if !ok { - return "", true - } - return v, true -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/request_id_retriever.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/request_id_retriever.go deleted file mode 100644 index 128b60a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/request_id_retriever.go +++ /dev/null @@ -1,57 +0,0 @@ -package middleware - -import ( - "context" - - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// AddRequestIDRetrieverMiddleware adds request id retriever middleware -func AddRequestIDRetrieverMiddleware(stack *middleware.Stack) error { - // add error wrapper middleware before operation deserializers so that it can wrap the error response - // returned by operation deserializers - return stack.Deserialize.Insert(&RequestIDRetriever{}, "OperationDeserializer", middleware.Before) -} - -// RequestIDRetriever middleware captures the AWS service request ID from the -// raw response. -type RequestIDRetriever struct { -} - -// ID returns the middleware identifier -func (m *RequestIDRetriever) ID() string { - return "RequestIDRetriever" -} - -// HandleDeserialize pulls the AWS request ID from the response, storing it in -// operation metadata. -func (m *RequestIDRetriever) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - - resp, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - // No raw response to wrap with. - return out, metadata, err - } - - // Different header which can map to request id - requestIDHeaderList := []string{"X-Amzn-Requestid", "X-Amz-RequestId"} - - for _, h := range requestIDHeaderList { - // check for headers known to contain Request id - if v := resp.Header.Get(h); len(v) != 0 { - // set reqID on metadata for successful responses. - SetRequestIDMetadata(&metadata, v) - - span, _ := tracing.GetSpan(ctx) - span.SetProperty("aws.request_id", v) - break - } - } - - return out, metadata, err -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go deleted file mode 100644 index 157a715..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go +++ /dev/null @@ -1,398 +0,0 @@ -package middleware - -import ( - "context" - "fmt" - "os" - "runtime" - "sort" - "strings" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -var languageVersion = strings.TrimPrefix(runtime.Version(), "go") - -// SDKAgentKeyType is the metadata type to add to the SDK agent string -type SDKAgentKeyType int - -// The set of valid SDKAgentKeyType constants. If an unknown value is assigned for SDKAgentKeyType it will -// be mapped to AdditionalMetadata. -const ( - _ SDKAgentKeyType = iota - APIMetadata - OperatingSystemMetadata - LanguageMetadata - EnvironmentMetadata - FeatureMetadata - ConfigMetadata - FrameworkMetadata - AdditionalMetadata - ApplicationIdentifier - FeatureMetadata2 -) - -// Hardcoded value to specify which version of the user agent we're using -const uaMetadata = "ua/2.1" - -func (k SDKAgentKeyType) string() string { - switch k { - case APIMetadata: - return "api" - case OperatingSystemMetadata: - return "os" - case LanguageMetadata: - return "lang" - case EnvironmentMetadata: - return "exec-env" - case FeatureMetadata: - return "ft" - case ConfigMetadata: - return "cfg" - case FrameworkMetadata: - return "lib" - case ApplicationIdentifier: - return "app" - case FeatureMetadata2: - return "m" - case AdditionalMetadata: - fallthrough - default: - return "md" - } -} - -const execEnvVar = `AWS_EXECUTION_ENV` - -var validChars = map[rune]bool{ - '!': true, '#': true, '$': true, '%': true, '&': true, '\'': true, '*': true, '+': true, - '-': true, '.': true, '^': true, '_': true, '`': true, '|': true, '~': true, -} - -// UserAgentFeature enumerates tracked SDK features. -type UserAgentFeature string - -// Enumerates UserAgentFeature. -const ( - UserAgentFeatureResourceModel UserAgentFeature = "A" // n/a (we don't generate separate resource types) - - UserAgentFeatureWaiter = "B" - UserAgentFeaturePaginator = "C" - - UserAgentFeatureRetryModeLegacy = "D" // n/a (equivalent to standard) - UserAgentFeatureRetryModeStandard = "E" - UserAgentFeatureRetryModeAdaptive = "F" - - UserAgentFeatureS3Transfer = "G" - UserAgentFeatureS3CryptoV1N = "H" // n/a (crypto client is external) - UserAgentFeatureS3CryptoV2 = "I" // n/a - UserAgentFeatureS3ExpressBucket = "J" - UserAgentFeatureS3AccessGrants = "K" // not yet implemented - - UserAgentFeatureGZIPRequestCompression = "L" - - UserAgentFeatureProtocolRPCV2CBOR = "M" - - UserAgentFeatureAccountIDEndpoint = "O" // DO NOT IMPLEMENT: rules output is not currently defined. SDKs should not parse endpoints for feature information. - UserAgentFeatureAccountIDModePreferred = "P" - UserAgentFeatureAccountIDModeDisabled = "Q" - UserAgentFeatureAccountIDModeRequired = "R" - - UserAgentFeatureRequestChecksumCRC32 = "U" - UserAgentFeatureRequestChecksumCRC32C = "V" - UserAgentFeatureRequestChecksumCRC64 = "W" - UserAgentFeatureRequestChecksumSHA1 = "X" - UserAgentFeatureRequestChecksumSHA256 = "Y" - UserAgentFeatureRequestChecksumWhenSupported = "Z" - UserAgentFeatureRequestChecksumWhenRequired = "a" - UserAgentFeatureResponseChecksumWhenSupported = "b" - UserAgentFeatureResponseChecksumWhenRequired = "c" - - UserAgentFeatureDynamoDBUserAgent = "d" // not yet implemented - - UserAgentFeatureCredentialsCode = "e" - UserAgentFeatureCredentialsJvmSystemProperties = "f" // n/a (this is not a JVM sdk) - UserAgentFeatureCredentialsEnvVars = "g" - UserAgentFeatureCredentialsEnvVarsStsWebIDToken = "h" - UserAgentFeatureCredentialsStsAssumeRole = "i" - UserAgentFeatureCredentialsStsAssumeRoleSaml = "j" // not yet implemented - UserAgentFeatureCredentialsStsAssumeRoleWebID = "k" - UserAgentFeatureCredentialsStsFederationToken = "l" // not yet implemented - UserAgentFeatureCredentialsStsSessionToken = "m" // not yet implemented - UserAgentFeatureCredentialsProfile = "n" - UserAgentFeatureCredentialsProfileSourceProfile = "o" - UserAgentFeatureCredentialsProfileNamedProvider = "p" - UserAgentFeatureCredentialsProfileStsWebIDToken = "q" - UserAgentFeatureCredentialsProfileSso = "r" - UserAgentFeatureCredentialsSso = "s" - UserAgentFeatureCredentialsProfileSsoLegacy = "t" - UserAgentFeatureCredentialsSsoLegacy = "u" - UserAgentFeatureCredentialsProfileProcess = "v" - UserAgentFeatureCredentialsProcess = "w" - UserAgentFeatureCredentialsBoto2ConfigFile = "x" // n/a (this is not boto/Python) - UserAgentFeatureCredentialsAwsSdkStore = "y" // n/a (this is used by .NET based sdk) - UserAgentFeatureCredentialsHTTP = "z" - UserAgentFeatureCredentialsIMDS = "0" - - UserAgentFeatureBearerServiceEnvVars = "3" - - UserAgentFeatureCredentialsProfileLogin = "AC" - UserAgentFeatureCredentialsLogin = "AD" -) - -var credentialSourceToFeature = map[aws.CredentialSource]UserAgentFeature{ - aws.CredentialSourceCode: UserAgentFeatureCredentialsCode, - aws.CredentialSourceEnvVars: UserAgentFeatureCredentialsEnvVars, - aws.CredentialSourceEnvVarsSTSWebIDToken: UserAgentFeatureCredentialsEnvVarsStsWebIDToken, - aws.CredentialSourceSTSAssumeRole: UserAgentFeatureCredentialsStsAssumeRole, - aws.CredentialSourceSTSAssumeRoleSaml: UserAgentFeatureCredentialsStsAssumeRoleSaml, - aws.CredentialSourceSTSAssumeRoleWebID: UserAgentFeatureCredentialsStsAssumeRoleWebID, - aws.CredentialSourceSTSFederationToken: UserAgentFeatureCredentialsStsFederationToken, - aws.CredentialSourceSTSSessionToken: UserAgentFeatureCredentialsStsSessionToken, - aws.CredentialSourceProfile: UserAgentFeatureCredentialsProfile, - aws.CredentialSourceProfileSourceProfile: UserAgentFeatureCredentialsProfileSourceProfile, - aws.CredentialSourceProfileNamedProvider: UserAgentFeatureCredentialsProfileNamedProvider, - aws.CredentialSourceProfileSTSWebIDToken: UserAgentFeatureCredentialsProfileStsWebIDToken, - aws.CredentialSourceProfileSSO: UserAgentFeatureCredentialsProfileSso, - aws.CredentialSourceSSO: UserAgentFeatureCredentialsSso, - aws.CredentialSourceProfileSSOLegacy: UserAgentFeatureCredentialsProfileSsoLegacy, - aws.CredentialSourceSSOLegacy: UserAgentFeatureCredentialsSsoLegacy, - aws.CredentialSourceProfileProcess: UserAgentFeatureCredentialsProfileProcess, - aws.CredentialSourceProcess: UserAgentFeatureCredentialsProcess, - aws.CredentialSourceHTTP: UserAgentFeatureCredentialsHTTP, - aws.CredentialSourceIMDS: UserAgentFeatureCredentialsIMDS, - aws.CredentialSourceProfileLogin: UserAgentFeatureCredentialsProfileLogin, - aws.CredentialSourceLogin: UserAgentFeatureCredentialsLogin, -} - -// RequestUserAgent is a build middleware that set the User-Agent for the request. -type RequestUserAgent struct { - sdkAgent, userAgent *smithyhttp.UserAgentBuilder - features map[UserAgentFeature]struct{} -} - -// NewRequestUserAgent returns a new requestUserAgent which will set the User-Agent and X-Amz-User-Agent for the -// request. -// -// User-Agent example: -// -// aws-sdk-go-v2/1.2.3 -// -// X-Amz-User-Agent example: -// -// aws-sdk-go-v2/1.2.3 md/GOOS/linux md/GOARCH/amd64 lang/go/1.15 -func NewRequestUserAgent() *RequestUserAgent { - userAgent, sdkAgent := smithyhttp.NewUserAgentBuilder(), smithyhttp.NewUserAgentBuilder() - addProductName(userAgent) - addUserAgentMetadata(userAgent) - addProductName(sdkAgent) - - r := &RequestUserAgent{ - sdkAgent: sdkAgent, - userAgent: userAgent, - features: map[UserAgentFeature]struct{}{}, - } - - addSDKMetadata(r) - - return r -} - -func addSDKMetadata(r *RequestUserAgent) { - r.AddSDKAgentKey(OperatingSystemMetadata, getNormalizedOSName()) - r.AddSDKAgentKeyValue(LanguageMetadata, "go", languageVersion) - r.AddSDKAgentKeyValue(AdditionalMetadata, "GOOS", runtime.GOOS) - r.AddSDKAgentKeyValue(AdditionalMetadata, "GOARCH", runtime.GOARCH) - if ev := os.Getenv(execEnvVar); len(ev) > 0 { - r.AddSDKAgentKey(EnvironmentMetadata, ev) - } -} - -func addProductName(builder *smithyhttp.UserAgentBuilder) { - builder.AddKeyValue(aws.SDKName, aws.SDKVersion) -} - -func addUserAgentMetadata(builder *smithyhttp.UserAgentBuilder) { - builder.AddKey(uaMetadata) -} - -// AddUserAgentKey retrieves a requestUserAgent from the provided stack, or initializes one. -func AddUserAgentKey(key string) func(*middleware.Stack) error { - return func(stack *middleware.Stack) error { - requestUserAgent, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - requestUserAgent.AddUserAgentKey(key) - return nil - } -} - -// AddUserAgentKeyValue retrieves a requestUserAgent from the provided stack, or initializes one. -func AddUserAgentKeyValue(key, value string) func(*middleware.Stack) error { - return func(stack *middleware.Stack) error { - requestUserAgent, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - requestUserAgent.AddUserAgentKeyValue(key, value) - return nil - } -} - -// AddSDKAgentKey retrieves a requestUserAgent from the provided stack, or initializes one. -func AddSDKAgentKey(keyType SDKAgentKeyType, key string) func(*middleware.Stack) error { - return func(stack *middleware.Stack) error { - requestUserAgent, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - requestUserAgent.AddSDKAgentKey(keyType, key) - return nil - } -} - -// AddSDKAgentKeyValue retrieves a requestUserAgent from the provided stack, or initializes one. -func AddSDKAgentKeyValue(keyType SDKAgentKeyType, key, value string) func(*middleware.Stack) error { - return func(stack *middleware.Stack) error { - requestUserAgent, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - requestUserAgent.AddSDKAgentKeyValue(keyType, key, value) - return nil - } -} - -// AddRequestUserAgentMiddleware registers a requestUserAgent middleware on the stack if not present. -func AddRequestUserAgentMiddleware(stack *middleware.Stack) error { - _, err := getOrAddRequestUserAgent(stack) - return err -} - -func getOrAddRequestUserAgent(stack *middleware.Stack) (*RequestUserAgent, error) { - id := (*RequestUserAgent)(nil).ID() - bm, ok := stack.Build.Get(id) - if !ok { - bm = NewRequestUserAgent() - err := stack.Build.Add(bm, middleware.After) - if err != nil { - return nil, err - } - } - - requestUserAgent, ok := bm.(*RequestUserAgent) - if !ok { - return nil, fmt.Errorf("%T for %s middleware did not match expected type", bm, id) - } - - return requestUserAgent, nil -} - -// AddUserAgentKey adds the component identified by name to the User-Agent string. -func (u *RequestUserAgent) AddUserAgentKey(key string) { - u.userAgent.AddKey(strings.Map(rules, key)) -} - -// AddUserAgentKeyValue adds the key identified by the given name and value to the User-Agent string. -func (u *RequestUserAgent) AddUserAgentKeyValue(key, value string) { - u.userAgent.AddKeyValue(strings.Map(rules, key), strings.Map(rules, value)) -} - -// AddUserAgentFeature adds the feature ID to the tracking list to be emitted -// in the final User-Agent string. -func (u *RequestUserAgent) AddUserAgentFeature(feature UserAgentFeature) { - u.features[feature] = struct{}{} -} - -// AddSDKAgentKey adds the component identified by name to the User-Agent string. -func (u *RequestUserAgent) AddSDKAgentKey(keyType SDKAgentKeyType, key string) { - // TODO: should target sdkAgent - u.userAgent.AddKey(keyType.string() + "/" + strings.Map(rules, key)) -} - -// AddSDKAgentKeyValue adds the key identified by the given name and value to the User-Agent string. -func (u *RequestUserAgent) AddSDKAgentKeyValue(keyType SDKAgentKeyType, key, value string) { - // TODO: should target sdkAgent - u.userAgent.AddKeyValue(keyType.string(), strings.Map(rules, key)+"#"+strings.Map(rules, value)) -} - -// AddCredentialsSource adds the credential source as a feature on the User-Agent string -func (u *RequestUserAgent) AddCredentialsSource(source aws.CredentialSource) { - x, ok := credentialSourceToFeature[source] - if ok { - u.AddUserAgentFeature(x) - } -} - -// ID the name of the middleware. -func (u *RequestUserAgent) ID() string { - return "UserAgent" -} - -// HandleBuild adds or appends the constructed user agent to the request. -func (u *RequestUserAgent) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - switch req := in.Request.(type) { - case *smithyhttp.Request: - u.addHTTPUserAgent(req) - // TODO: To be re-enabled - // u.addHTTPSDKAgent(req) - default: - return out, metadata, fmt.Errorf("unknown transport type %T", in) - } - - return next.HandleBuild(ctx, in) -} - -func (u *RequestUserAgent) addHTTPUserAgent(request *smithyhttp.Request) { - const userAgent = "User-Agent" - if len(u.features) > 0 { - updateHTTPHeader(request, userAgent, buildFeatureMetrics(u.features)) - } - updateHTTPHeader(request, userAgent, u.userAgent.Build()) -} - -func (u *RequestUserAgent) addHTTPSDKAgent(request *smithyhttp.Request) { - const sdkAgent = "X-Amz-User-Agent" - updateHTTPHeader(request, sdkAgent, u.sdkAgent.Build()) -} - -func updateHTTPHeader(request *smithyhttp.Request, header string, value string) { - var current string - if v := request.Header[header]; len(v) > 0 { - current = v[0] - } - if len(current) > 0 { - current = value + " " + current - } else { - current = value - } - request.Header[header] = append(request.Header[header][:0], current) -} - -func rules(r rune) rune { - switch { - case r >= '0' && r <= '9': - return r - case r >= 'A' && r <= 'Z' || r >= 'a' && r <= 'z': - return r - case validChars[r]: - return r - default: - return '-' - } -} - -func buildFeatureMetrics(features map[UserAgentFeature]struct{}) string { - fs := make([]string, 0, len(features)) - for f := range features { - fs = append(fs, string(f)) - } - - sort.Strings(fs) - return fmt.Sprintf("%s/%s", FeatureMetadata2.string(), strings.Join(fs, ",")) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/array.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/array.go deleted file mode 100644 index 6669a3d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/array.go +++ /dev/null @@ -1,61 +0,0 @@ -package query - -import ( - "net/url" - "strconv" -) - -// Array represents the encoding of Query lists and sets. A Query array is a -// representation of a list of values of a fixed type. A serialized array might -// look like the following: -// -// ListName.member.1=foo -// &ListName.member.2=bar -// &Listname.member.3=baz -type Array struct { - // The query values to add the array to. - values url.Values - // The array's prefix, which includes the names of all parent structures - // and ends with the name of the list. For example, the prefix might be - // "ParentStructure.ListName". This prefix will be used to form the full - // keys for each element in the list. For example, an entry might have the - // key "ParentStructure.ListName.member.MemberName.1". - // - // When the array is not flat the prefix will contain the memberName otherwise the memberName is ignored - prefix string - // Elements are stored in values, so we keep track of the list size here. - size int32 - // Empty lists are encoded as "=", if we add a value later we will - // remove this encoding - emptyValue Value -} - -func newArray(values url.Values, prefix string, flat bool, memberName string) *Array { - emptyValue := newValue(values, prefix, flat) - emptyValue.String("") - - if !flat { - // This uses string concatenation in place of fmt.Sprintf as fmt.Sprintf has a much higher resource overhead - prefix = prefix + keySeparator + memberName - } - - return &Array{ - values: values, - prefix: prefix, - emptyValue: emptyValue, - } -} - -// Value adds a new element to the Query Array. Returns a Value type used to -// encode the array element. -func (a *Array) Value() Value { - if a.size == 0 { - delete(a.values, a.emptyValue.key) - } - - // Query lists start a 1, so adjust the size first - a.size++ - // Lists can't have flat members - // This uses string concatenation in place of fmt.Sprintf as fmt.Sprintf has a much higher resource overhead - return newValue(a.values, a.prefix+keySeparator+strconv.FormatInt(int64(a.size), 10), false) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/encoder.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/encoder.go deleted file mode 100644 index 2ecf924..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/encoder.go +++ /dev/null @@ -1,80 +0,0 @@ -package query - -import ( - "io" - "net/url" - "sort" -) - -// Encoder is a Query encoder that supports construction of Query body -// values using methods. -type Encoder struct { - // The query values that will be built up to manage encoding. - values url.Values - // The writer that the encoded body will be written to. - writer io.Writer - Value -} - -// NewEncoder returns a new Query body encoder -func NewEncoder(writer io.Writer) *Encoder { - values := url.Values{} - return &Encoder{ - values: values, - writer: writer, - Value: newBaseValue(values), - } -} - -// Encode returns the []byte slice representing the current -// state of the Query encoder. -func (e Encoder) Encode() error { - ws, ok := e.writer.(interface{ WriteString(string) (int, error) }) - if !ok { - // Fall back to less optimal byte slice casting if WriteString isn't available. - ws = &wrapWriteString{writer: e.writer} - } - - // Get the keys and sort them to have a stable output - keys := make([]string, 0, len(e.values)) - for k := range e.values { - keys = append(keys, k) - } - sort.Strings(keys) - isFirstEntry := true - for _, key := range keys { - queryValues := e.values[key] - escapedKey := url.QueryEscape(key) - for _, value := range queryValues { - if !isFirstEntry { - if _, err := ws.WriteString(`&`); err != nil { - return err - } - } else { - isFirstEntry = false - } - if _, err := ws.WriteString(escapedKey); err != nil { - return err - } - if _, err := ws.WriteString(`=`); err != nil { - return err - } - if _, err := ws.WriteString(url.QueryEscape(value)); err != nil { - return err - } - } - } - return nil -} - -// wrapWriteString wraps an io.Writer to provide a WriteString method -// where one is not available. -type wrapWriteString struct { - writer io.Writer -} - -// WriteString writes a string to the wrapped writer by casting it to -// a byte array first. -func (w wrapWriteString) WriteString(v string) (int, error) { - return w.writer.Write([]byte(v)) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/map.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/map.go deleted file mode 100644 index dea242b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/map.go +++ /dev/null @@ -1,78 +0,0 @@ -package query - -import ( - "fmt" - "net/url" -) - -// Map represents the encoding of Query maps. A Query map is a representation -// of a mapping of arbitrary string keys to arbitrary values of a fixed type. -// A Map differs from an Object in that the set of keys is not fixed, in that -// the values must all be of the same type, and that map entries are ordered. -// A serialized map might look like the following: -// -// MapName.entry.1.key=Foo -// &MapName.entry.1.value=spam -// &MapName.entry.2.key=Bar -// &MapName.entry.2.value=eggs -type Map struct { - // The query values to add the map to. - values url.Values - // The map's prefix, which includes the names of all parent structures - // and ends with the name of the object. For example, the prefix might be - // "ParentStructure.MapName". This prefix will be used to form the full - // keys for each key-value pair of the map. For example, a value might have - // the key "ParentStructure.MapName.1.value". - // - // While this is currently represented as a string that gets added to, it - // could also be represented as a stack that only gets condensed into a - // string when a finalized key is created. This could potentially reduce - // allocations. - prefix string - // Whether the map is flat or not. A map that is not flat will produce the - // following entries to the url.Values for a given key-value pair: - // MapName.entry.1.KeyLocationName=mykey - // MapName.entry.1.ValueLocationName=myvalue - // A map that is flat will produce the following: - // MapName.1.KeyLocationName=mykey - // MapName.1.ValueLocationName=myvalue - flat bool - // The location name of the key. In most cases this should be "key". - keyLocationName string - // The location name of the value. In most cases this should be "value". - valueLocationName string - // Elements are stored in values, so we keep track of the list size here. - size int32 -} - -func newMap(values url.Values, prefix string, flat bool, keyLocationName string, valueLocationName string) *Map { - return &Map{ - values: values, - prefix: prefix, - flat: flat, - keyLocationName: keyLocationName, - valueLocationName: valueLocationName, - } -} - -// Key adds the given named key to the Query map. -// Returns a Value encoder that should be used to encode a Query value type. -func (m *Map) Key(name string) Value { - // Query lists start a 1, so adjust the size first - m.size++ - var key string - var value string - if m.flat { - key = fmt.Sprintf("%s.%d.%s", m.prefix, m.size, m.keyLocationName) - value = fmt.Sprintf("%s.%d.%s", m.prefix, m.size, m.valueLocationName) - } else { - key = fmt.Sprintf("%s.entry.%d.%s", m.prefix, m.size, m.keyLocationName) - value = fmt.Sprintf("%s.entry.%d.%s", m.prefix, m.size, m.valueLocationName) - } - - // The key can only be a string, so we just go ahead and set it here - newValue(m.values, key, false).String(name) - - // Maps can't have flat members - return newValue(m.values, value, false) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/middleware.go deleted file mode 100644 index 3603447..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/middleware.go +++ /dev/null @@ -1,62 +0,0 @@ -package query - -import ( - "context" - "fmt" - "io/ioutil" - - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// AddAsGetRequestMiddleware adds a middleware to the Serialize stack after the -// operation serializer that will convert the query request body to a GET -// operation with the query message in the HTTP request querystring. -func AddAsGetRequestMiddleware(stack *middleware.Stack) error { - return stack.Serialize.Insert(&asGetRequest{}, "OperationSerializer", middleware.After) -} - -type asGetRequest struct{} - -func (*asGetRequest) ID() string { return "Query:AsGetRequest" } - -func (m *asGetRequest) HandleSerialize( - ctx context.Context, input middleware.SerializeInput, next middleware.SerializeHandler, -) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - req, ok := input.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("expect smithy HTTP Request, got %T", input.Request) - } - - req.Method = "GET" - - // If the stream is not set, nothing else to do. - stream := req.GetStream() - if stream == nil { - return next.HandleSerialize(ctx, input) - } - - // Clear the stream since there will not be any body. - req.Header.Del("Content-Type") - req, err = req.SetStream(nil) - if err != nil { - return out, metadata, fmt.Errorf("unable update request body %w", err) - } - input.Request = req - - // Update request query with the body's query string value. - delim := "" - if len(req.URL.RawQuery) != 0 { - delim = "&" - } - - b, err := ioutil.ReadAll(stream) - if err != nil { - return out, metadata, fmt.Errorf("unable to get request body %w", err) - } - req.URL.RawQuery += delim + string(b) - - return next.HandleSerialize(ctx, input) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/object.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/object.go deleted file mode 100644 index 305a8ac..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/object.go +++ /dev/null @@ -1,68 +0,0 @@ -package query - -import "net/url" - -// Object represents the encoding of Query structures and unions. A Query -// object is a representation of a mapping of string keys to arbitrary -// values where there is a fixed set of keys whose values each have their -// own known type. A serialized object might look like the following: -// -// ObjectName.Foo=value -// &ObjectName.Bar=5 -type Object struct { - // The query values to add the object to. - values url.Values - // The object's prefix, which includes the names of all parent structures - // and ends with the name of the object. For example, the prefix might be - // "ParentStructure.ObjectName". This prefix will be used to form the full - // keys for each member of the object. For example, a member might have the - // key "ParentStructure.ObjectName.MemberName". - // - // While this is currently represented as a string that gets added to, it - // could also be represented as a stack that only gets condensed into a - // string when a finalized key is created. This could potentially reduce - // allocations. - prefix string -} - -func newObject(values url.Values, prefix string) *Object { - return &Object{ - values: values, - prefix: prefix, - } -} - -// Key adds the given named key to the Query object. -// Returns a Value encoder that should be used to encode a Query value type. -func (o *Object) Key(name string) Value { - return o.key(name, false) -} - -// KeyWithValues adds the given named key to the Query object. -// Returns a Value encoder that should be used to encode a Query list of values. -func (o *Object) KeyWithValues(name string) Value { - return o.keyWithValues(name, false) -} - -// FlatKey adds the given named key to the Query object. -// Returns a Value encoder that should be used to encode a Query value type. The -// value will be flattened if it is a map or array. -func (o *Object) FlatKey(name string) Value { - return o.key(name, true) -} - -func (o *Object) key(name string, flatValue bool) Value { - if o.prefix != "" { - // This uses string concatenation in place of fmt.Sprintf as fmt.Sprintf has a much higher resource overhead - return newValue(o.values, o.prefix+keySeparator+name, flatValue) - } - return newValue(o.values, name, flatValue) -} - -func (o *Object) keyWithValues(name string, flatValue bool) Value { - if o.prefix != "" { - // This uses string concatenation in place of fmt.Sprintf as fmt.Sprintf has a much higher resource overhead - return newAppendValue(o.values, o.prefix+keySeparator+name, flatValue) - } - return newAppendValue(o.values, name, flatValue) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/value.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/value.go deleted file mode 100644 index 8063c59..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/value.go +++ /dev/null @@ -1,117 +0,0 @@ -package query - -import ( - "math/big" - "net/url" - - "github.com/aws/smithy-go/encoding/httpbinding" -) - -const keySeparator = "." - -// Value represents a Query Value type. -type Value struct { - // The query values to add the value to. - values url.Values - // The value's key, which will form the prefix for complex types. - key string - // Whether the value should be flattened or not if it's a flattenable type. - flat bool - queryValue httpbinding.QueryValue -} - -func newValue(values url.Values, key string, flat bool) Value { - return Value{ - values: values, - key: key, - flat: flat, - queryValue: httpbinding.NewQueryValue(values, key, false), - } -} - -func newAppendValue(values url.Values, key string, flat bool) Value { - return Value{ - values: values, - key: key, - flat: flat, - queryValue: httpbinding.NewQueryValue(values, key, true), - } -} - -func newBaseValue(values url.Values) Value { - return Value{ - values: values, - queryValue: httpbinding.NewQueryValue(nil, "", false), - } -} - -// Array returns a new Array encoder. -func (qv Value) Array(locationName string) *Array { - return newArray(qv.values, qv.key, qv.flat, locationName) -} - -// Object returns a new Object encoder. -func (qv Value) Object() *Object { - return newObject(qv.values, qv.key) -} - -// Map returns a new Map encoder. -func (qv Value) Map(keyLocationName string, valueLocationName string) *Map { - return newMap(qv.values, qv.key, qv.flat, keyLocationName, valueLocationName) -} - -// Base64EncodeBytes encodes v as a base64 query string value. -// This is intended to enable compatibility with the JSON encoder. -func (qv Value) Base64EncodeBytes(v []byte) { - qv.queryValue.Blob(v) -} - -// Boolean encodes v as a query string value -func (qv Value) Boolean(v bool) { - qv.queryValue.Boolean(v) -} - -// String encodes v as a query string value -func (qv Value) String(v string) { - qv.queryValue.String(v) -} - -// Byte encodes v as a query string value -func (qv Value) Byte(v int8) { - qv.queryValue.Byte(v) -} - -// Short encodes v as a query string value -func (qv Value) Short(v int16) { - qv.queryValue.Short(v) -} - -// Integer encodes v as a query string value -func (qv Value) Integer(v int32) { - qv.queryValue.Integer(v) -} - -// Long encodes v as a query string value -func (qv Value) Long(v int64) { - qv.queryValue.Long(v) -} - -// Float encodes v as a query string value -func (qv Value) Float(v float32) { - qv.queryValue.Float(v) -} - -// Double encodes v as a query string value -func (qv Value) Double(v float64) { - qv.queryValue.Double(v) -} - -// BigInteger encodes v as a query string value -func (qv Value) BigInteger(v *big.Int) { - qv.queryValue.BigInteger(v) -} - -// BigDecimal encodes v as a query string value -func (qv Value) BigDecimal(v *big.Float) { - qv.queryValue.BigDecimal(v) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/restjson/decoder_util.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/restjson/decoder_util.go deleted file mode 100644 index 1bce78a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/restjson/decoder_util.go +++ /dev/null @@ -1,85 +0,0 @@ -package restjson - -import ( - "encoding/json" - "io" - "strings" - - "github.com/aws/smithy-go" -) - -// GetErrorInfo util looks for code, __type, and message members in the -// json body. These members are optionally available, and the function -// returns the value of member if it is available. This function is useful to -// identify the error code, msg in a REST JSON error response. -func GetErrorInfo(decoder *json.Decoder) (errorType string, message string, err error) { - var errInfo struct { - Code string - Type string `json:"__type"` - Message string - } - - err = decoder.Decode(&errInfo) - if err != nil { - if err == io.EOF { - return errorType, message, nil - } - return errorType, message, err - } - - // assign error type - if len(errInfo.Code) != 0 { - errorType = errInfo.Code - } else if len(errInfo.Type) != 0 { - errorType = errInfo.Type - } - - // assign error message - if len(errInfo.Message) != 0 { - message = errInfo.Message - } - - // sanitize error - if len(errorType) != 0 { - errorType = SanitizeErrorCode(errorType) - } - - return errorType, message, nil -} - -// SanitizeErrorCode sanitizes the errorCode string . -// The rule for sanitizing is if a `:` character is present, then take only the -// contents before the first : character in the value. -// If a # character is present, then take only the contents after the -// first # character in the value. -func SanitizeErrorCode(errorCode string) string { - if strings.ContainsAny(errorCode, ":") { - errorCode = strings.SplitN(errorCode, ":", 2)[0] - } - - if strings.ContainsAny(errorCode, "#") { - errorCode = strings.SplitN(errorCode, "#", 2)[1] - } - - return errorCode -} - -// GetSmithyGenericAPIError returns smithy generic api error and an error interface. -// Takes in json decoder, and error Code string as args. The function retrieves error message -// and error code from the decoder body. If errorCode of length greater than 0 is passed in as -// an argument, it is used instead. -func GetSmithyGenericAPIError(decoder *json.Decoder, errorCode string) (*smithy.GenericAPIError, error) { - errorType, message, err := GetErrorInfo(decoder) - if err != nil { - return nil, err - } - - if len(errorCode) == 0 { - errorCode = errorType - } - - return &smithy.GenericAPIError{ - Code: errorCode, - Message: message, - }, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/xml/error_utils.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/xml/error_utils.go deleted file mode 100644 index 6975ce6..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/xml/error_utils.go +++ /dev/null @@ -1,48 +0,0 @@ -package xml - -import ( - "encoding/xml" - "fmt" - "io" -) - -// ErrorComponents represents the error response fields -// that will be deserialized from an xml error response body -type ErrorComponents struct { - Code string - Message string - RequestID string -} - -// GetErrorResponseComponents returns the error fields from an xml error response body -func GetErrorResponseComponents(r io.Reader, noErrorWrapping bool) (ErrorComponents, error) { - if noErrorWrapping { - var errResponse noWrappedErrorResponse - if err := xml.NewDecoder(r).Decode(&errResponse); err != nil && err != io.EOF { - return ErrorComponents{}, fmt.Errorf("error while deserializing xml error response: %w", err) - } - return ErrorComponents(errResponse), nil - } - - var errResponse wrappedErrorResponse - if err := xml.NewDecoder(r).Decode(&errResponse); err != nil && err != io.EOF { - return ErrorComponents{}, fmt.Errorf("error while deserializing xml error response: %w", err) - } - return ErrorComponents(errResponse), nil -} - -// noWrappedErrorResponse represents the error response body with -// no internal Error wrapping -type noWrappedErrorResponse struct { - Code string `xml:"Code"` - Message string `xml:"Message"` - RequestID string `xml:"RequestId"` -} - -// wrappedErrorResponse represents the error response body -// wrapped within Error -type wrappedErrorResponse struct { - Code string `xml:"Error>Code"` - Message string `xml:"Error>Message"` - RequestID string `xml:"RequestId"` -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/none.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/none.go deleted file mode 100644 index 8c78364..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/none.go +++ /dev/null @@ -1,20 +0,0 @@ -package ratelimit - -import "context" - -// None implements a no-op rate limiter which effectively disables client-side -// rate limiting (also known as "retry quotas"). -// -// GetToken does nothing and always returns a nil error. The returned -// token-release function does nothing, and always returns a nil error. -// -// AddTokens does nothing and always returns a nil error. -var None = &none{} - -type none struct{} - -func (*none) GetToken(ctx context.Context, cost uint) (func() error, error) { - return func() error { return nil }, nil -} - -func (*none) AddTokens(v uint) error { return nil } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/token_bucket.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/token_bucket.go deleted file mode 100644 index 974ef59..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/token_bucket.go +++ /dev/null @@ -1,96 +0,0 @@ -package ratelimit - -import ( - "sync" -) - -// TokenBucket provides a concurrency safe utility for adding and removing -// tokens from the available token bucket. -type TokenBucket struct { - remainingTokens uint - maxCapacity uint - minCapacity uint - mu sync.Mutex -} - -// NewTokenBucket returns an initialized TokenBucket with the capacity -// specified. -func NewTokenBucket(i uint) *TokenBucket { - return &TokenBucket{ - remainingTokens: i, - maxCapacity: i, - minCapacity: 1, - } -} - -// Retrieve attempts to reduce the available tokens by the amount requested. If -// there are tokens available true will be returned along with the number of -// available tokens remaining. If amount requested is larger than the available -// capacity, false will be returned along with the available capacity. If the -// amount is less than the available capacity, the capacity will be reduced by -// that amount, and the remaining capacity and true will be returned. -func (t *TokenBucket) Retrieve(amount uint) (available uint, retrieved bool) { - t.mu.Lock() - defer t.mu.Unlock() - - if amount > t.remainingTokens { - return t.remainingTokens, false - } - - t.remainingTokens -= amount - return t.remainingTokens, true -} - -// Refund returns the amount of tokens back to the available token bucket, up -// to the initial capacity. -func (t *TokenBucket) Refund(amount uint) { - t.mu.Lock() - defer t.mu.Unlock() - - // Capacity cannot exceed max capacity. - t.remainingTokens = uintMin(t.remainingTokens+amount, t.maxCapacity) -} - -// Capacity returns the maximum capacity of tokens that the bucket could -// contain. -func (t *TokenBucket) Capacity() uint { - t.mu.Lock() - defer t.mu.Unlock() - - return t.maxCapacity -} - -// Remaining returns the number of tokens that remaining in the bucket. -func (t *TokenBucket) Remaining() uint { - t.mu.Lock() - defer t.mu.Unlock() - - return t.remainingTokens -} - -// Resize adjusts the size of the token bucket. Returns the capacity remaining. -func (t *TokenBucket) Resize(size uint) uint { - t.mu.Lock() - defer t.mu.Unlock() - - t.maxCapacity = uintMax(size, t.minCapacity) - - // Capacity needs to be capped at max capacity, if max size reduced. - t.remainingTokens = uintMin(t.remainingTokens, t.maxCapacity) - - return t.remainingTokens -} - -func uintMin(a, b uint) uint { - if a < b { - return a - } - return b -} - -func uintMax(a, b uint) uint { - if a > b { - return a - } - return b -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/token_rate_limit.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/token_rate_limit.go deleted file mode 100644 index d89090a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/token_rate_limit.go +++ /dev/null @@ -1,83 +0,0 @@ -package ratelimit - -import ( - "context" - "fmt" -) - -type rateToken struct { - tokenCost uint - bucket *TokenBucket -} - -func (t rateToken) release() error { - t.bucket.Refund(t.tokenCost) - return nil -} - -// TokenRateLimit provides a Token Bucket RateLimiter implementation -// that limits the overall number of retry attempts that can be made across -// operation invocations. -type TokenRateLimit struct { - bucket *TokenBucket -} - -// NewTokenRateLimit returns an TokenRateLimit with default values. -// Functional options can configure the retry rate limiter. -func NewTokenRateLimit(tokens uint) *TokenRateLimit { - return &TokenRateLimit{ - bucket: NewTokenBucket(tokens), - } -} - -type canceledError struct { - Err error -} - -func (c canceledError) CanceledError() bool { return true } -func (c canceledError) Unwrap() error { return c.Err } -func (c canceledError) Error() string { - return fmt.Sprintf("canceled, %v", c.Err) -} - -// GetToken may cause a available pool of retry quota to be -// decremented. Will return an error if the decremented value can not be -// reduced from the retry quota. -func (l *TokenRateLimit) GetToken(ctx context.Context, cost uint) (func() error, error) { - select { - case <-ctx.Done(): - return nil, canceledError{Err: ctx.Err()} - default: - } - if avail, ok := l.bucket.Retrieve(cost); !ok { - return nil, QuotaExceededError{Available: avail, Requested: cost} - } - - return rateToken{ - tokenCost: cost, - bucket: l.bucket, - }.release, nil -} - -// AddTokens increments the token bucket by a fixed amount. -func (l *TokenRateLimit) AddTokens(v uint) error { - l.bucket.Refund(v) - return nil -} - -// Remaining returns the number of remaining tokens in the bucket. -func (l *TokenRateLimit) Remaining() uint { - return l.bucket.Remaining() -} - -// QuotaExceededError provides the SDK error when the retries for a given -// token bucket have been exhausted. -type QuotaExceededError struct { - Available uint - Requested uint -} - -func (e QuotaExceededError) Error() string { - return fmt.Sprintf("retry quota exceeded, %d available, %d requested", - e.Available, e.Requested) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/request.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/request.go deleted file mode 100644 index d8d00e6..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/request.go +++ /dev/null @@ -1,25 +0,0 @@ -package aws - -import ( - "fmt" -) - -// TODO remove replace with smithy.CanceledError - -// RequestCanceledError is the error that will be returned by an API request -// that was canceled. Requests given a Context may return this error when -// canceled. -type RequestCanceledError struct { - Err error -} - -// CanceledError returns true to satisfy interfaces checking for canceled errors. -func (*RequestCanceledError) CanceledError() bool { return true } - -// Unwrap returns the underlying error, if there was one. -func (e *RequestCanceledError) Unwrap() error { - return e.Err -} -func (e *RequestCanceledError) Error() string { - return fmt.Sprintf("request canceled, %v", e.Err) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive.go deleted file mode 100644 index 4dfde85..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive.go +++ /dev/null @@ -1,156 +0,0 @@ -package retry - -import ( - "context" - "fmt" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/internal/sdk" -) - -const ( - // DefaultRequestCost is the cost of a single request from the adaptive - // rate limited token bucket. - DefaultRequestCost uint = 1 -) - -// DefaultThrottles provides the set of errors considered throttle errors that -// are checked by default. -var DefaultThrottles = []IsErrorThrottle{ - ThrottleErrorCode{ - Codes: DefaultThrottleErrorCodes, - }, -} - -// AdaptiveModeOptions provides the functional options for configuring the -// adaptive retry mode, and delay behavior. -type AdaptiveModeOptions struct { - // If the adaptive token bucket is empty, when an attempt will be made - // AdaptiveMode will sleep until a token is available. This can occur when - // attempts fail with throttle errors. Use this option to disable the sleep - // until token is available, and return error immediately. - FailOnNoAttemptTokens bool - - // The cost of an attempt from the AdaptiveMode's adaptive token bucket. - RequestCost uint - - // Set of strategies to determine if the attempt failed due to a throttle - // error. - // - // It is safe to append to this list in NewAdaptiveMode's functional options. - Throttles []IsErrorThrottle - - // Set of options for standard retry mode that AdaptiveMode is built on top - // of. AdaptiveMode may apply its own defaults to Standard retry mode that - // are different than the defaults of NewStandard. Use these options to - // override the default options. - StandardOptions []func(*StandardOptions) -} - -// AdaptiveMode provides an experimental retry strategy that expands on the -// Standard retry strategy, adding client attempt rate limits. The attempt rate -// limit is initially unrestricted, but becomes restricted when the attempt -// fails with for a throttle error. When restricted AdaptiveMode may need to -// sleep before an attempt is made, if too many throttles have been received. -// AdaptiveMode's sleep can be canceled with context cancel. Set -// AdaptiveModeOptions FailOnNoAttemptTokens to change the behavior from sleep, -// to fail fast. -// -// Eventually unrestricted attempt rate limit will be restored once attempts no -// longer are failing due to throttle errors. -type AdaptiveMode struct { - options AdaptiveModeOptions - throttles IsErrorThrottles - - retryer aws.RetryerV2 - rateLimit *adaptiveRateLimit -} - -// NewAdaptiveMode returns an initialized AdaptiveMode retry strategy. -func NewAdaptiveMode(optFns ...func(*AdaptiveModeOptions)) *AdaptiveMode { - o := AdaptiveModeOptions{ - RequestCost: DefaultRequestCost, - Throttles: append([]IsErrorThrottle{}, DefaultThrottles...), - } - for _, fn := range optFns { - fn(&o) - } - - return &AdaptiveMode{ - options: o, - throttles: IsErrorThrottles(o.Throttles), - retryer: NewStandard(o.StandardOptions...), - rateLimit: newAdaptiveRateLimit(), - } -} - -// IsErrorRetryable returns if the failed attempt is retryable. This check -// should determine if the error can be retried, or if the error is -// terminal. -func (a *AdaptiveMode) IsErrorRetryable(err error) bool { - return a.retryer.IsErrorRetryable(err) -} - -// MaxAttempts returns the maximum number of attempts that can be made for -// an attempt before failing. A value of 0 implies that the attempt should -// be retried until it succeeds if the errors are retryable. -func (a *AdaptiveMode) MaxAttempts() int { - return a.retryer.MaxAttempts() -} - -// RetryDelay returns the delay that should be used before retrying the -// attempt. Will return error if the if the delay could not be determined. -func (a *AdaptiveMode) RetryDelay(attempt int, opErr error) ( - time.Duration, error, -) { - return a.retryer.RetryDelay(attempt, opErr) -} - -// GetRetryToken attempts to deduct the retry cost from the retry token pool. -// Returning the token release function, or error. -func (a *AdaptiveMode) GetRetryToken(ctx context.Context, opErr error) ( - releaseToken func(error) error, err error, -) { - return a.retryer.GetRetryToken(ctx, opErr) -} - -// GetInitialToken returns the initial attempt token that can increment the -// retry token pool if the attempt is successful. -// -// Deprecated: This method does not provide a way to block using Context, -// nor can it return an error. Use RetryerV2, and GetAttemptToken instead. Only -// present to implement Retryer interface. -func (a *AdaptiveMode) GetInitialToken() (releaseToken func(error) error) { - return nopRelease -} - -// GetAttemptToken returns the attempt token that can be used to rate limit -// attempt calls. Will be used by the SDK's retry package's Attempt -// middleware to get an attempt token prior to calling the temp and releasing -// the attempt token after the attempt has been made. -func (a *AdaptiveMode) GetAttemptToken(ctx context.Context) (func(error) error, error) { - for { - acquiredToken, waitTryAgain := a.rateLimit.AcquireToken(a.options.RequestCost) - if acquiredToken { - break - } - if a.options.FailOnNoAttemptTokens { - return nil, fmt.Errorf( - "unable to get attempt token, and FailOnNoAttemptTokens enables") - } - - if err := sdk.SleepWithContext(ctx, waitTryAgain); err != nil { - return nil, fmt.Errorf("failed to wait for token to be available, %w", err) - } - } - - return a.handleResponse, nil -} - -func (a *AdaptiveMode) handleResponse(opErr error) error { - throttled := a.throttles.IsErrorThrottle(opErr).Bool() - - a.rateLimit.Update(throttled) - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive_ratelimit.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive_ratelimit.go deleted file mode 100644 index ad96d9b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive_ratelimit.go +++ /dev/null @@ -1,158 +0,0 @@ -package retry - -import ( - "math" - "sync" - "time" - - "github.com/aws/aws-sdk-go-v2/internal/sdk" -) - -type adaptiveRateLimit struct { - tokenBucketEnabled bool - - smooth float64 - beta float64 - scaleConstant float64 - minFillRate float64 - - fillRate float64 - calculatedRate float64 - lastRefilled time.Time - measuredTxRate float64 - lastTxRateBucket float64 - requestCount int64 - lastMaxRate float64 - lastThrottleTime time.Time - timeWindow float64 - - tokenBucket *adaptiveTokenBucket - - mu sync.Mutex -} - -func newAdaptiveRateLimit() *adaptiveRateLimit { - now := sdk.NowTime() - return &adaptiveRateLimit{ - smooth: 0.8, - beta: 0.7, - scaleConstant: 0.4, - - minFillRate: 0.5, - - lastTxRateBucket: math.Floor(timeFloat64Seconds(now)), - lastThrottleTime: now, - - tokenBucket: newAdaptiveTokenBucket(0), - } -} - -func (a *adaptiveRateLimit) Enable(v bool) { - a.mu.Lock() - defer a.mu.Unlock() - - a.tokenBucketEnabled = v -} - -func (a *adaptiveRateLimit) AcquireToken(amount uint) ( - tokenAcquired bool, waitTryAgain time.Duration, -) { - a.mu.Lock() - defer a.mu.Unlock() - - if !a.tokenBucketEnabled { - return true, 0 - } - - a.tokenBucketRefill() - - available, ok := a.tokenBucket.Retrieve(float64(amount)) - if !ok { - waitDur := float64Seconds((float64(amount) - available) / a.fillRate) - return false, waitDur - } - - return true, 0 -} - -func (a *adaptiveRateLimit) Update(throttled bool) { - a.mu.Lock() - defer a.mu.Unlock() - - a.updateMeasuredRate() - - if throttled { - rateToUse := a.measuredTxRate - if a.tokenBucketEnabled { - rateToUse = math.Min(a.measuredTxRate, a.fillRate) - } - - a.lastMaxRate = rateToUse - a.calculateTimeWindow() - a.lastThrottleTime = sdk.NowTime() - a.calculatedRate = a.cubicThrottle(rateToUse) - a.tokenBucketEnabled = true - } else { - a.calculateTimeWindow() - a.calculatedRate = a.cubicSuccess(sdk.NowTime()) - } - - newRate := math.Min(a.calculatedRate, 2*a.measuredTxRate) - a.tokenBucketUpdateRate(newRate) -} - -func (a *adaptiveRateLimit) cubicSuccess(t time.Time) float64 { - dt := secondsFloat64(t.Sub(a.lastThrottleTime)) - return (a.scaleConstant * math.Pow(dt-a.timeWindow, 3)) + a.lastMaxRate -} - -func (a *adaptiveRateLimit) cubicThrottle(rateToUse float64) float64 { - return rateToUse * a.beta -} - -func (a *adaptiveRateLimit) calculateTimeWindow() { - a.timeWindow = math.Pow((a.lastMaxRate*(1.-a.beta))/a.scaleConstant, 1./3.) -} - -func (a *adaptiveRateLimit) tokenBucketUpdateRate(newRPS float64) { - a.tokenBucketRefill() - a.fillRate = math.Max(newRPS, a.minFillRate) - a.tokenBucket.Resize(newRPS) -} - -func (a *adaptiveRateLimit) updateMeasuredRate() { - now := sdk.NowTime() - timeBucket := math.Floor(timeFloat64Seconds(now)*2.) / 2. - a.requestCount++ - - if timeBucket > a.lastTxRateBucket { - currentRate := float64(a.requestCount) / (timeBucket - a.lastTxRateBucket) - a.measuredTxRate = (currentRate * a.smooth) + (a.measuredTxRate * (1. - a.smooth)) - a.requestCount = 0 - a.lastTxRateBucket = timeBucket - } -} - -func (a *adaptiveRateLimit) tokenBucketRefill() { - now := sdk.NowTime() - if a.lastRefilled.IsZero() { - a.lastRefilled = now - return - } - - fillAmount := secondsFloat64(now.Sub(a.lastRefilled)) * a.fillRate - a.tokenBucket.Refund(fillAmount) - a.lastRefilled = now -} - -func float64Seconds(v float64) time.Duration { - return time.Duration(v * float64(time.Second)) -} - -func secondsFloat64(v time.Duration) float64 { - return float64(v) / float64(time.Second) -} - -func timeFloat64Seconds(v time.Time) float64 { - return float64(v.UnixNano()) / float64(time.Second) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive_token_bucket.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive_token_bucket.go deleted file mode 100644 index 052723e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive_token_bucket.go +++ /dev/null @@ -1,83 +0,0 @@ -package retry - -import ( - "math" - "sync" -) - -// adaptiveTokenBucket provides a concurrency safe utility for adding and -// removing tokens from the available token bucket. -type adaptiveTokenBucket struct { - remainingTokens float64 - maxCapacity float64 - minCapacity float64 - mu sync.Mutex -} - -// newAdaptiveTokenBucket returns an initialized adaptiveTokenBucket with the -// capacity specified. -func newAdaptiveTokenBucket(i float64) *adaptiveTokenBucket { - return &adaptiveTokenBucket{ - remainingTokens: i, - maxCapacity: i, - minCapacity: 1, - } -} - -// Retrieve attempts to reduce the available tokens by the amount requested. If -// there are tokens available true will be returned along with the number of -// available tokens remaining. If amount requested is larger than the available -// capacity, false will be returned along with the available capacity. If the -// amount is less than the available capacity, the capacity will be reduced by -// that amount, and the remaining capacity and true will be returned. -func (t *adaptiveTokenBucket) Retrieve(amount float64) (available float64, retrieved bool) { - t.mu.Lock() - defer t.mu.Unlock() - - if amount > t.remainingTokens { - return t.remainingTokens, false - } - - t.remainingTokens -= amount - return t.remainingTokens, true -} - -// Refund returns the amount of tokens back to the available token bucket, up -// to the initial capacity. -func (t *adaptiveTokenBucket) Refund(amount float64) { - t.mu.Lock() - defer t.mu.Unlock() - - // Capacity cannot exceed max capacity. - t.remainingTokens = math.Min(t.remainingTokens+amount, t.maxCapacity) -} - -// Capacity returns the maximum capacity of tokens that the bucket could -// contain. -func (t *adaptiveTokenBucket) Capacity() float64 { - t.mu.Lock() - defer t.mu.Unlock() - - return t.maxCapacity -} - -// Remaining returns the number of tokens that remaining in the bucket. -func (t *adaptiveTokenBucket) Remaining() float64 { - t.mu.Lock() - defer t.mu.Unlock() - - return t.remainingTokens -} - -// Resize adjusts the size of the token bucket. Returns the capacity remaining. -func (t *adaptiveTokenBucket) Resize(size float64) float64 { - t.mu.Lock() - defer t.mu.Unlock() - - t.maxCapacity = math.Max(size, t.minCapacity) - - // Capacity needs to be capped at max capacity, if max size reduced. - t.remainingTokens = math.Min(t.remainingTokens, t.maxCapacity) - - return t.remainingTokens -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/attempt_metrics.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/attempt_metrics.go deleted file mode 100644 index bfa5bf7..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/attempt_metrics.go +++ /dev/null @@ -1,51 +0,0 @@ -package retry - -import ( - "context" - - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" -) - -type attemptMetrics struct { - Attempts metrics.Int64Counter - Errors metrics.Int64Counter - - AttemptDuration metrics.Float64Histogram -} - -func newAttemptMetrics(meter metrics.Meter) (*attemptMetrics, error) { - m := &attemptMetrics{} - var err error - - m.Attempts, err = meter.Int64Counter("client.call.attempts", func(o *metrics.InstrumentOptions) { - o.UnitLabel = "{attempt}" - o.Description = "The number of attempts for an individual operation" - }) - if err != nil { - return nil, err - } - m.Errors, err = meter.Int64Counter("client.call.errors", func(o *metrics.InstrumentOptions) { - o.UnitLabel = "{error}" - o.Description = "The number of errors for an operation" - }) - if err != nil { - return nil, err - } - m.AttemptDuration, err = meter.Float64Histogram("client.call.attempt_duration", func(o *metrics.InstrumentOptions) { - o.UnitLabel = "s" - o.Description = "The time it takes to connect to the service, send the request, and get back HTTP status code and headers (including time queued waiting to be sent)" - }) - if err != nil { - return nil, err - } - - return m, nil -} - -func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { - return func(o *metrics.RecordMetricOptions) { - o.Properties.Set("rpc.service", middleware.GetServiceID(ctx)) - o.Properties.Set("rpc.method", middleware.GetOperationName(ctx)) - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/doc.go deleted file mode 100644 index 3a08ebe..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/doc.go +++ /dev/null @@ -1,80 +0,0 @@ -// Package retry provides interfaces and implementations for SDK request retry behavior. -// -// # Retryer Interface and Implementations -// -// This package defines Retryer interface that is used to either implement custom retry behavior -// or to extend the existing retry implementations provided by the SDK. This package provides a single -// retry implementation: Standard. -// -// # Standard -// -// Standard is the default retryer implementation used by service clients. The standard retryer is a rate limited -// retryer that has a configurable max attempts to limit the number of retry attempts when a retryable error occurs. -// In addition, the retryer uses a configurable token bucket to rate limit the retry attempts across the client, -// and uses an additional delay policy to limit the time between a requests subsequent attempts. -// -// By default the standard retryer uses the DefaultRetryables slice of IsErrorRetryable types to determine whether -// a given error is retryable. By default this list of retryables includes the following: -// - Retrying errors that implement the RetryableError method, and return true. -// - Connection Errors -// - Errors that implement a ConnectionError, Temporary, or Timeout method that return true. -// - Connection Reset Errors. -// - net.OpErr types that are dialing errors or are temporary. -// - HTTP Status Codes: 500, 502, 503, and 504. -// - API Error Codes -// - RequestTimeout, RequestTimeoutException -// - Throttling, ThrottlingException, ThrottledException, RequestThrottledException, TooManyRequestsException, -// RequestThrottled, SlowDown, EC2ThrottledException -// - ProvisionedThroughputExceededException, RequestLimitExceeded, BandwidthLimitExceeded, LimitExceededException -// - TransactionInProgressException, PriorRequestNotComplete -// -// The standard retryer will not retry a request in the event if the context associated with the request -// has been cancelled. Applications must handle this case explicitly if they wish to retry with a different context -// value. -// -// You can configure the standard retryer implementation to fit your applications by constructing a standard retryer -// using the NewStandard function, and providing one more functional argument that mutate the StandardOptions -// structure. StandardOptions provides the ability to modify the token bucket rate limiter, retryable error conditions, -// and the retry delay policy. -// -// For example to modify the default retry attempts for the standard retryer: -// -// // configure the custom retryer -// customRetry := retry.NewStandard(func(o *retry.StandardOptions) { -// o.MaxAttempts = 5 -// }) -// -// // create a service client with the retryer -// s3.NewFromConfig(cfg, func(o *s3.Options) { -// o.Retryer = customRetry -// }) -// -// # Utilities -// -// A number of package functions have been provided to easily wrap retryer implementations in an implementation agnostic -// way. These are: -// -// AddWithErrorCodes - Provides the ability to add additional API error codes that should be considered retryable -// in addition to those considered retryable by the provided retryer. -// -// AddWithMaxAttempts - Provides the ability to set the max number of attempts for retrying a request by wrapping -// a retryer implementation. -// -// AddWithMaxBackoffDelay - Provides the ability to set the max back off delay that can occur before retrying a -// request by wrapping a retryer implementation. -// -// The following package functions have been provided to easily satisfy different retry interfaces to further customize -// a given retryer's behavior: -// -// BackoffDelayerFunc - Can be used to wrap a function to satisfy the BackoffDelayer interface. For example, -// you can use this method to easily create custom back off policies to be used with the -// standard retryer. -// -// IsErrorRetryableFunc - Can be used to wrap a function to satisfy the IsErrorRetryable interface. For example, -// this can be used to extend the standard retryer to add additional logic to determine if an -// error should be retried. -// -// IsErrorTimeoutFunc - Can be used to wrap a function to satisfy IsErrorTimeout interface. For example, -// this can be used to extend the standard retryer to add additional logic to determine if an -// error should be considered a timeout. -package retry diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/errors.go deleted file mode 100644 index 3e432ee..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/errors.go +++ /dev/null @@ -1,20 +0,0 @@ -package retry - -import "fmt" - -// MaxAttemptsError provides the error when the maximum number of attempts have -// been exceeded. -type MaxAttemptsError struct { - Attempt int - Err error -} - -func (e *MaxAttemptsError) Error() string { - return fmt.Sprintf("exceeded maximum number of attempts, %d, %v", e.Attempt, e.Err) -} - -// Unwrap returns the nested error causing the max attempts error. Provides the -// implementation for errors.Is and errors.As to unwrap nested errors. -func (e *MaxAttemptsError) Unwrap() error { - return e.Err -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/jitter_backoff.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/jitter_backoff.go deleted file mode 100644 index c266996..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/jitter_backoff.go +++ /dev/null @@ -1,49 +0,0 @@ -package retry - -import ( - "math" - "time" - - "github.com/aws/aws-sdk-go-v2/internal/rand" - "github.com/aws/aws-sdk-go-v2/internal/timeconv" -) - -// ExponentialJitterBackoff provides backoff delays with jitter based on the -// number of attempts. -type ExponentialJitterBackoff struct { - maxBackoff time.Duration - // precomputed number of attempts needed to reach max backoff. - maxBackoffAttempts float64 - - randFloat64 func() (float64, error) -} - -// NewExponentialJitterBackoff returns an ExponentialJitterBackoff configured -// for the max backoff. -func NewExponentialJitterBackoff(maxBackoff time.Duration) *ExponentialJitterBackoff { - return &ExponentialJitterBackoff{ - maxBackoff: maxBackoff, - maxBackoffAttempts: math.Log2( - float64(maxBackoff) / float64(time.Second)), - randFloat64: rand.CryptoRandFloat64, - } -} - -// BackoffDelay returns the duration to wait before the next attempt should be -// made. Returns an error if unable get a duration. -func (j *ExponentialJitterBackoff) BackoffDelay(attempt int, err error) (time.Duration, error) { - if attempt > int(j.maxBackoffAttempts) { - return j.maxBackoff, nil - } - - b, err := j.randFloat64() - if err != nil { - return 0, err - } - - // [0.0, 1.0) * 2 ^ attempts - ri := int64(1 << uint64(attempt)) - delaySeconds := b * float64(ri) - - return timeconv.FloatSecondsDur(delaySeconds), nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/metadata.go deleted file mode 100644 index 7a3f183..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/metadata.go +++ /dev/null @@ -1,52 +0,0 @@ -package retry - -import ( - awsmiddle "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/smithy-go/middleware" -) - -// attemptResultsKey is a metadata accessor key to retrieve metadata -// for all request attempts. -type attemptResultsKey struct { -} - -// GetAttemptResults retrieves attempts results from middleware metadata. -func GetAttemptResults(metadata middleware.Metadata) (AttemptResults, bool) { - m, ok := metadata.Get(attemptResultsKey{}).(AttemptResults) - return m, ok -} - -// AttemptResults represents struct containing metadata returned by all request attempts. -type AttemptResults struct { - - // Results is a slice consisting attempt result from all request attempts. - // Results are stored in order request attempt is made. - Results []AttemptResult -} - -// AttemptResult represents attempt result returned by a single request attempt. -type AttemptResult struct { - - // Err is the error if received for the request attempt. - Err error - - // Retryable denotes if request may be retried. This states if an - // error is considered retryable. - Retryable bool - - // Retried indicates if this request was retried. - Retried bool - - // ResponseMetadata is any existing metadata passed via the response middlewares. - ResponseMetadata middleware.Metadata -} - -// addAttemptResults adds attempt results to middleware metadata -func addAttemptResults(metadata *middleware.Metadata, v AttemptResults) { - metadata.Set(attemptResultsKey{}, v) -} - -// GetRawResponse returns raw response recorded for the attempt result -func (a AttemptResult) GetRawResponse() interface{} { - return awsmiddle.GetRawResponse(a.ResponseMetadata) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go deleted file mode 100644 index 5549922..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go +++ /dev/null @@ -1,418 +0,0 @@ -package retry - -import ( - "context" - "errors" - "fmt" - "strconv" - "strings" - "time" - - internalcontext "github.com/aws/aws-sdk-go-v2/internal/context" - "github.com/aws/smithy-go" - - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddle "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/metrics" - smithymiddle "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - "github.com/aws/smithy-go/transport/http" -) - -// RequestCloner is a function that can take an input request type and clone -// the request for use in a subsequent retry attempt. -type RequestCloner func(interface{}) interface{} - -type retryMetadata struct { - AttemptNum int - AttemptTime time.Time - MaxAttempts int - AttemptClockSkew time.Duration -} - -// Attempt is a Smithy Finalize middleware that handles retry attempts using -// the provided Retryer implementation. -type Attempt struct { - // Enable the logging of retry attempts performed by the SDK. This will - // include logging retry attempts, unretryable errors, and when max - // attempts are reached. - LogAttempts bool - - // A Meter instance for recording retry-related metrics. - OperationMeter metrics.Meter - - retryer aws.RetryerV2 - requestCloner RequestCloner -} - -// define the threshold at which we will consider certain kind of errors to be probably -// caused by clock skew -const skewThreshold = 4 * time.Minute - -// NewAttemptMiddleware returns a new Attempt retry middleware. -func NewAttemptMiddleware(retryer aws.Retryer, requestCloner RequestCloner, optFns ...func(*Attempt)) *Attempt { - m := &Attempt{ - retryer: wrapAsRetryerV2(retryer), - requestCloner: requestCloner, - } - for _, fn := range optFns { - fn(m) - } - if m.OperationMeter == nil { - m.OperationMeter = metrics.NopMeterProvider{}.Meter("") - } - - return m -} - -// ID returns the middleware identifier -func (r *Attempt) ID() string { return "Retry" } - -func (r Attempt) logf(logger logging.Logger, classification logging.Classification, format string, v ...interface{}) { - if !r.LogAttempts { - return - } - logger.Logf(classification, format, v...) -} - -// HandleFinalize utilizes the provider Retryer implementation to attempt -// retries over the next handler -func (r *Attempt) HandleFinalize(ctx context.Context, in smithymiddle.FinalizeInput, next smithymiddle.FinalizeHandler) ( - out smithymiddle.FinalizeOutput, metadata smithymiddle.Metadata, err error, -) { - var attemptNum int - var attemptClockSkew time.Duration - var attemptResults AttemptResults - - maxAttempts := r.retryer.MaxAttempts() - releaseRetryToken := nopRelease - - retryMetrics, err := newAttemptMetrics(r.OperationMeter) - if err != nil { - return out, metadata, err - } - - for { - attemptNum++ - attemptInput := in - attemptInput.Request = r.requestCloner(attemptInput.Request) - - // Record the metadata for the for attempt being started. - attemptCtx := setRetryMetadata(ctx, retryMetadata{ - AttemptNum: attemptNum, - AttemptTime: sdk.NowTime().UTC(), - MaxAttempts: maxAttempts, - AttemptClockSkew: attemptClockSkew, - }) - - // Setting clock skew to be used on other context (like signing) - ctx = internalcontext.SetAttemptSkewContext(ctx, attemptClockSkew) - - var attemptResult AttemptResult - - attemptCtx, span := tracing.StartSpan(attemptCtx, "Attempt", func(o *tracing.SpanOptions) { - o.Properties.Set("operation.attempt", attemptNum) - }) - retryMetrics.Attempts.Add(ctx, 1, withOperationMetadata(ctx)) - - start := sdk.NowTime() - out, attemptResult, releaseRetryToken, err = r.handleAttempt(attemptCtx, attemptInput, releaseRetryToken, next) - elapsed := sdk.NowTime().Sub(start) - - retryMetrics.AttemptDuration.Record(ctx, float64(elapsed)/1e9, withOperationMetadata(ctx)) - if err != nil { - retryMetrics.Errors.Add(ctx, 1, withOperationMetadata(ctx), func(o *metrics.RecordMetricOptions) { - o.Properties.Set("exception.type", errorType(err)) - }) - } - - span.End() - - attemptClockSkew, _ = awsmiddle.GetAttemptSkew(attemptResult.ResponseMetadata) - - // AttemptResult Retried states that the attempt was not successful, and - // should be retried. - shouldRetry := attemptResult.Retried - - // Add attempt metadata to list of all attempt metadata - attemptResults.Results = append(attemptResults.Results, attemptResult) - - if !shouldRetry { - // Ensure the last response's metadata is used as the bases for result - // metadata returned by the stack. The Slice of attempt results - // will be added to this cloned metadata. - metadata = attemptResult.ResponseMetadata.Clone() - - break - } - } - - addAttemptResults(&metadata, attemptResults) - return out, metadata, err -} - -// handleAttempt handles an individual request attempt. -func (r *Attempt) handleAttempt( - ctx context.Context, in smithymiddle.FinalizeInput, releaseRetryToken func(error) error, next smithymiddle.FinalizeHandler, -) ( - out smithymiddle.FinalizeOutput, attemptResult AttemptResult, _ func(error) error, err error, -) { - defer func() { - attemptResult.Err = err - }() - - // Short circuit if this attempt never can succeed because the context is - // canceled. This reduces the chance of token pools being modified for - // attempts that will not be made - select { - case <-ctx.Done(): - return out, attemptResult, nopRelease, ctx.Err() - default: - } - - //------------------------------ - // Get Attempt Token - //------------------------------ - releaseAttemptToken, err := r.retryer.GetAttemptToken(ctx) - if err != nil { - return out, attemptResult, nopRelease, fmt.Errorf( - "failed to get retry Send token, %w", err) - } - - //------------------------------ - // Send Attempt - //------------------------------ - logger := smithymiddle.GetLogger(ctx) - service, operation := awsmiddle.GetServiceID(ctx), awsmiddle.GetOperationName(ctx) - retryMetadata, _ := getRetryMetadata(ctx) - attemptNum := retryMetadata.AttemptNum - maxAttempts := retryMetadata.MaxAttempts - - // Following attempts must ensure the request payload stream starts in a - // rewound state. - if attemptNum > 1 { - if rewindable, ok := in.Request.(interface{ RewindStream() error }); ok { - if rewindErr := rewindable.RewindStream(); rewindErr != nil { - return out, attemptResult, nopRelease, fmt.Errorf( - "failed to rewind transport stream for retry, %w", rewindErr) - } - } - - r.logf(logger, logging.Debug, "retrying request %s/%s, attempt %d", - service, operation, attemptNum) - } - - var metadata smithymiddle.Metadata - out, metadata, err = next.HandleFinalize(ctx, in) - attemptResult.ResponseMetadata = metadata - - //------------------------------ - // Bookkeeping - //------------------------------ - // Release the retry token based on the state of the attempt's error (if any). - if releaseError := releaseRetryToken(err); releaseError != nil && err != nil { - return out, attemptResult, nopRelease, fmt.Errorf( - "failed to release retry token after request error, %w", err) - } - // Release the attempt token based on the state of the attempt's error (if any). - if releaseError := releaseAttemptToken(err); releaseError != nil && err != nil { - return out, attemptResult, nopRelease, fmt.Errorf( - "failed to release initial token after request error, %w", err) - } - // If there was no error making the attempt, nothing further to do. There - // will be nothing to retry. - if err == nil { - return out, attemptResult, nopRelease, err - } - - err = wrapAsClockSkew(ctx, err) - - //------------------------------ - // Is Retryable and Should Retry - //------------------------------ - // If the attempt failed with an unretryable error, nothing further to do - // but return, and inform the caller about the terminal failure. - retryable := r.retryer.IsErrorRetryable(err) - if !retryable { - r.logf(logger, logging.Debug, "request failed with unretryable error %v", err) - return out, attemptResult, nopRelease, err - } - - // set retryable to true - attemptResult.Retryable = true - - // Once the maximum number of attempts have been exhausted there is nothing - // further to do other than inform the caller about the terminal failure. - if maxAttempts > 0 && attemptNum >= maxAttempts { - r.logf(logger, logging.Debug, "max retry attempts exhausted, max %d", maxAttempts) - err = &MaxAttemptsError{ - Attempt: attemptNum, - Err: err, - } - return out, attemptResult, nopRelease, err - } - - //------------------------------ - // Get Retry (aka Retry Quota) Token - //------------------------------ - // Get a retry token that will be released after the - releaseRetryToken, retryTokenErr := r.retryer.GetRetryToken(ctx, err) - if retryTokenErr != nil { - return out, attemptResult, nopRelease, errors.Join(err, retryTokenErr) - } - - //------------------------------ - // Retry Delay and Sleep - //------------------------------ - // Get the retry delay before another attempt can be made, and sleep for - // that time. Potentially early exist if the sleep is canceled via the - // context. - retryDelay, reqErr := r.retryer.RetryDelay(attemptNum, err) - if reqErr != nil { - return out, attemptResult, releaseRetryToken, reqErr - } - if reqErr = sdk.SleepWithContext(ctx, retryDelay); reqErr != nil { - err = &aws.RequestCanceledError{Err: reqErr} - return out, attemptResult, releaseRetryToken, err - } - - // The request should be re-attempted. - attemptResult.Retried = true - - return out, attemptResult, releaseRetryToken, err -} - -// errors that, if detected when we know there's a clock skew, -// can be retried and have a high chance of success -var possibleSkewCodes = map[string]struct{}{ - "InvalidSignatureException": {}, - "SignatureDoesNotMatch": {}, - "AuthFailure": {}, -} - -var definiteSkewCodes = map[string]struct{}{ - "RequestExpired": {}, - "RequestInTheFuture": {}, - "RequestTimeTooSkewed": {}, -} - -// wrapAsClockSkew checks if this error could be related to a clock skew -// error and if so, wrap the error. -func wrapAsClockSkew(ctx context.Context, err error) error { - var v interface{ ErrorCode() string } - if !errors.As(err, &v) { - return err - } - if _, ok := definiteSkewCodes[v.ErrorCode()]; ok { - return &retryableClockSkewError{Err: err} - } - _, isPossibleSkewCode := possibleSkewCodes[v.ErrorCode()] - if skew := internalcontext.GetAttemptSkewContext(ctx); skew > skewThreshold && isPossibleSkewCode { - return &retryableClockSkewError{Err: err} - } - return err -} - -// MetricsHeader attaches SDK request metric header for retries to the transport -type MetricsHeader struct{} - -// ID returns the middleware identifier -func (r *MetricsHeader) ID() string { - return "RetryMetricsHeader" -} - -// HandleFinalize attaches the SDK request metric header to the transport layer -func (r MetricsHeader) HandleFinalize(ctx context.Context, in smithymiddle.FinalizeInput, next smithymiddle.FinalizeHandler) ( - out smithymiddle.FinalizeOutput, metadata smithymiddle.Metadata, err error, -) { - retryMetadata, _ := getRetryMetadata(ctx) - - const retryMetricHeader = "Amz-Sdk-Request" - var parts []string - - parts = append(parts, "attempt="+strconv.Itoa(retryMetadata.AttemptNum)) - if retryMetadata.MaxAttempts != 0 { - parts = append(parts, "max="+strconv.Itoa(retryMetadata.MaxAttempts)) - } - - var ttl time.Time - if deadline, ok := ctx.Deadline(); ok { - ttl = deadline - } - - // Only append the TTL if it can be determined. - if !ttl.IsZero() && retryMetadata.AttemptClockSkew > 0 { - const unixTimeFormat = "20060102T150405Z" - ttl = ttl.Add(retryMetadata.AttemptClockSkew) - parts = append(parts, "ttl="+ttl.Format(unixTimeFormat)) - } - - switch req := in.Request.(type) { - case *http.Request: - req.Header[retryMetricHeader] = append(req.Header[retryMetricHeader][:0], strings.Join(parts, "; ")) - default: - return out, metadata, fmt.Errorf("unknown transport type %T", req) - } - - return next.HandleFinalize(ctx, in) -} - -type retryMetadataKey struct{} - -// getRetryMetadata retrieves retryMetadata from the context and a bool -// indicating if it was set. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func getRetryMetadata(ctx context.Context) (metadata retryMetadata, ok bool) { - metadata, ok = smithymiddle.GetStackValue(ctx, retryMetadataKey{}).(retryMetadata) - return metadata, ok -} - -// setRetryMetadata sets the retryMetadata on the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func setRetryMetadata(ctx context.Context, metadata retryMetadata) context.Context { - return smithymiddle.WithStackValue(ctx, retryMetadataKey{}, metadata) -} - -// AddRetryMiddlewaresOptions is the set of options that can be passed to -// AddRetryMiddlewares for configuring retry associated middleware. -type AddRetryMiddlewaresOptions struct { - Retryer aws.Retryer - - // Enable the logging of retry attempts performed by the SDK. This will - // include logging retry attempts, unretryable errors, and when max - // attempts are reached. - LogRetryAttempts bool -} - -// AddRetryMiddlewares adds retry middleware to operation middleware stack -func AddRetryMiddlewares(stack *smithymiddle.Stack, options AddRetryMiddlewaresOptions) error { - attempt := NewAttemptMiddleware(options.Retryer, http.RequestCloner, func(middleware *Attempt) { - middleware.LogAttempts = options.LogRetryAttempts - }) - - // index retry to before signing, if signing exists - if err := stack.Finalize.Insert(attempt, "Signing", smithymiddle.Before); err != nil { - return err - } - - if err := stack.Finalize.Insert(&MetricsHeader{}, attempt.ID(), smithymiddle.After); err != nil { - return err - } - return nil -} - -// Determines the value of exception.type for metrics purposes. We prefer an -// API-specific error code, otherwise it's just the Go type for the value. -func errorType(err error) string { - var terr smithy.APIError - if errors.As(err, &terr) { - return terr.ErrorCode() - } - return fmt.Sprintf("%T", err) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/retry.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/retry.go deleted file mode 100644 index af81635..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/retry.go +++ /dev/null @@ -1,90 +0,0 @@ -package retry - -import ( - "context" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -// AddWithErrorCodes returns a Retryer with additional error codes considered -// for determining if the error should be retried. -func AddWithErrorCodes(r aws.Retryer, codes ...string) aws.Retryer { - retryable := &RetryableErrorCode{ - Codes: map[string]struct{}{}, - } - for _, c := range codes { - retryable.Codes[c] = struct{}{} - } - - return &withIsErrorRetryable{ - RetryerV2: wrapAsRetryerV2(r), - Retryable: retryable, - } -} - -type withIsErrorRetryable struct { - aws.RetryerV2 - Retryable IsErrorRetryable -} - -func (r *withIsErrorRetryable) IsErrorRetryable(err error) bool { - if v := r.Retryable.IsErrorRetryable(err); v != aws.UnknownTernary { - return v.Bool() - } - return r.RetryerV2.IsErrorRetryable(err) -} - -// AddWithMaxAttempts returns a Retryer with MaxAttempts set to the value -// specified. -func AddWithMaxAttempts(r aws.Retryer, max int) aws.Retryer { - return &withMaxAttempts{ - RetryerV2: wrapAsRetryerV2(r), - Max: max, - } -} - -type withMaxAttempts struct { - aws.RetryerV2 - Max int -} - -func (w *withMaxAttempts) MaxAttempts() int { - return w.Max -} - -// AddWithMaxBackoffDelay returns a retryer wrapping the passed in retryer -// overriding the RetryDelay behavior for a alternate minimum initial backoff -// delay. -func AddWithMaxBackoffDelay(r aws.Retryer, delay time.Duration) aws.Retryer { - return &withMaxBackoffDelay{ - RetryerV2: wrapAsRetryerV2(r), - backoff: NewExponentialJitterBackoff(delay), - } -} - -type withMaxBackoffDelay struct { - aws.RetryerV2 - backoff *ExponentialJitterBackoff -} - -func (r *withMaxBackoffDelay) RetryDelay(attempt int, err error) (time.Duration, error) { - return r.backoff.BackoffDelay(attempt, err) -} - -type wrappedAsRetryerV2 struct { - aws.Retryer -} - -func wrapAsRetryerV2(r aws.Retryer) aws.RetryerV2 { - v, ok := r.(aws.RetryerV2) - if !ok { - v = wrappedAsRetryerV2{Retryer: r} - } - - return v -} - -func (w wrappedAsRetryerV2) GetAttemptToken(context.Context) (func(error) error, error) { - return w.Retryer.GetInitialToken(), nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/retryable_error.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/retryable_error.go deleted file mode 100644 index 1b485f9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/retryable_error.go +++ /dev/null @@ -1,228 +0,0 @@ -package retry - -import ( - "errors" - "fmt" - "net" - "net/url" - "strings" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -// IsErrorRetryable provides the interface of an implementation to determine if -// a error as the result of an operation is retryable. -type IsErrorRetryable interface { - IsErrorRetryable(error) aws.Ternary -} - -// IsErrorRetryables is a collection of checks to determine of the error is -// retryable. Iterates through the checks and returns the state of retryable -// if any check returns something other than unknown. -type IsErrorRetryables []IsErrorRetryable - -// IsErrorRetryable returns if the error is retryable if any of the checks in -// the list return a value other than unknown. -func (r IsErrorRetryables) IsErrorRetryable(err error) aws.Ternary { - for _, re := range r { - if v := re.IsErrorRetryable(err); v != aws.UnknownTernary { - return v - } - } - return aws.UnknownTernary -} - -// IsErrorRetryableFunc wraps a function with the IsErrorRetryable interface. -type IsErrorRetryableFunc func(error) aws.Ternary - -// IsErrorRetryable returns if the error is retryable. -func (fn IsErrorRetryableFunc) IsErrorRetryable(err error) aws.Ternary { - return fn(err) -} - -// RetryableError is an IsErrorRetryable implementation which uses the -// optional interface Retryable on the error value to determine if the error is -// retryable. -type RetryableError struct{} - -// IsErrorRetryable returns if the error is retryable if it satisfies the -// Retryable interface, and returns if the attempt should be retried. -func (RetryableError) IsErrorRetryable(err error) aws.Ternary { - var v interface{ RetryableError() bool } - - if !errors.As(err, &v) { - return aws.UnknownTernary - } - - return aws.BoolTernary(v.RetryableError()) -} - -// NoRetryCanceledError detects if the error was an request canceled error and -// returns if so. -type NoRetryCanceledError struct{} - -// IsErrorRetryable returns the error is not retryable if the request was -// canceled. -func (NoRetryCanceledError) IsErrorRetryable(err error) aws.Ternary { - var v interface{ CanceledError() bool } - - if !errors.As(err, &v) { - return aws.UnknownTernary - } - - if v.CanceledError() { - return aws.FalseTernary - } - return aws.UnknownTernary -} - -// RetryableConnectionError determines if the underlying error is an HTTP -// connection and returns if it should be retried. -// -// Includes errors such as connection reset, connection refused, net dial, -// temporary, and timeout errors. -type RetryableConnectionError struct{} - -// IsErrorRetryable returns if the error is caused by and HTTP connection -// error, and should be retried. -func (r RetryableConnectionError) IsErrorRetryable(err error) aws.Ternary { - if err == nil { - return aws.UnknownTernary - } - var retryable bool - - var conErr interface{ ConnectionError() bool } - var tempErr interface{ Temporary() bool } - var timeoutErr interface{ Timeout() bool } - var urlErr *url.Error - var netOpErr *net.OpError - var dnsError *net.DNSError - - if errors.As(err, &dnsError) { - // NXDOMAIN errors should not be retried - if dnsError.IsNotFound { - return aws.BoolTernary(false) - } - - // if !dnsError.Temporary(), error may or may not be temporary, - // (i.e. !Temporary() =/=> !retryable) so we should fall through to - // remaining checks - if dnsError.Temporary() { - return aws.BoolTernary(true) - } - } - - switch { - case errors.As(err, &conErr) && conErr.ConnectionError(): - retryable = true - - case strings.Contains(err.Error(), "use of closed network connection"): - fallthrough - case strings.Contains(err.Error(), "connection reset"): - // The errors "connection reset" and "use of closed network connection" - // are effectively the same. It appears to be the difference between - // sync and async read of TCP RST in the stdlib's net.Conn read loop. - // see #2737 - retryable = true - - case errors.As(err, &urlErr): - // Refused connections should be retried as the service may not yet be - // running on the port. Go TCP dial considers refused connections as - // not temporary. - if strings.Contains(urlErr.Error(), "connection refused") { - retryable = true - } else { - return r.IsErrorRetryable(errors.Unwrap(urlErr)) - } - - case errors.As(err, &netOpErr): - // Network dial, or temporary network errors are always retryable. - if strings.EqualFold(netOpErr.Op, "dial") || netOpErr.Temporary() { - retryable = true - } else { - return r.IsErrorRetryable(errors.Unwrap(netOpErr)) - } - - case errors.As(err, &tempErr) && tempErr.Temporary(): - // Fallback to the generic temporary check, with temporary errors - // retryable. - retryable = true - - case errors.As(err, &timeoutErr) && timeoutErr.Timeout(): - // Fallback to the generic timeout check, with timeout errors - // retryable. - retryable = true - - default: - return aws.UnknownTernary - } - - return aws.BoolTernary(retryable) - -} - -// RetryableHTTPStatusCode provides a IsErrorRetryable based on HTTP status -// codes. -type RetryableHTTPStatusCode struct { - Codes map[int]struct{} -} - -// IsErrorRetryable return if the passed in error is retryable based on the -// HTTP status code. -func (r RetryableHTTPStatusCode) IsErrorRetryable(err error) aws.Ternary { - var v interface{ HTTPStatusCode() int } - - if !errors.As(err, &v) { - return aws.UnknownTernary - } - - _, ok := r.Codes[v.HTTPStatusCode()] - if !ok { - return aws.UnknownTernary - } - - return aws.TrueTernary -} - -// RetryableErrorCode determines if an attempt should be retried based on the -// API error code. -type RetryableErrorCode struct { - Codes map[string]struct{} -} - -// IsErrorRetryable return if the error is retryable based on the error codes. -// Returns unknown if the error doesn't have a code or it is unknown. -func (r RetryableErrorCode) IsErrorRetryable(err error) aws.Ternary { - var v interface{ ErrorCode() string } - - if !errors.As(err, &v) { - return aws.UnknownTernary - } - - _, ok := r.Codes[v.ErrorCode()] - if !ok { - return aws.UnknownTernary - } - - return aws.TrueTernary -} - -// retryableClockSkewError marks errors that can be caused by clock skew -// (difference between server time and client time). -// This is returned when there's certain confidence that adjusting the client time -// could allow a retry to succeed -type retryableClockSkewError struct{ Err error } - -func (e *retryableClockSkewError) Error() string { - return fmt.Sprintf("Probable clock skew error: %v", e.Err) -} - -// Unwrap returns the wrapped error. -func (e *retryableClockSkewError) Unwrap() error { - return e.Err -} - -// RetryableError allows the retryer to retry this request -func (e *retryableClockSkewError) RetryableError() bool { - return true -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/standard.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/standard.go deleted file mode 100644 index d5ea932..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/standard.go +++ /dev/null @@ -1,269 +0,0 @@ -package retry - -import ( - "context" - "fmt" - "time" - - "github.com/aws/aws-sdk-go-v2/aws/ratelimit" -) - -// BackoffDelayer provides the interface for determining the delay to before -// another request attempt, that previously failed. -type BackoffDelayer interface { - BackoffDelay(attempt int, err error) (time.Duration, error) -} - -// BackoffDelayerFunc provides a wrapper around a function to determine the -// backoff delay of an attempt retry. -type BackoffDelayerFunc func(int, error) (time.Duration, error) - -// BackoffDelay returns the delay before attempt to retry a request. -func (fn BackoffDelayerFunc) BackoffDelay(attempt int, err error) (time.Duration, error) { - return fn(attempt, err) -} - -const ( - // DefaultMaxAttempts is the maximum of attempts for an API request - DefaultMaxAttempts int = 3 - - // DefaultMaxBackoff is the maximum back off delay between attempts - DefaultMaxBackoff time.Duration = 20 * time.Second -) - -// Default retry token quota values. -const ( - DefaultRetryRateTokens uint = 500 - DefaultRetryCost uint = 5 - DefaultRetryTimeoutCost uint = 10 - DefaultNoRetryIncrement uint = 1 -) - -// DefaultRetryableHTTPStatusCodes is the default set of HTTP status codes the SDK -// should consider as retryable errors. -var DefaultRetryableHTTPStatusCodes = map[int]struct{}{ - 500: {}, - 502: {}, - 503: {}, - 504: {}, -} - -// DefaultRetryableErrorCodes provides the set of API error codes that should -// be retried. -var DefaultRetryableErrorCodes = map[string]struct{}{ - "RequestTimeout": {}, - "RequestTimeoutException": {}, -} - -// DefaultThrottleErrorCodes provides the set of API error codes that are -// considered throttle errors. -var DefaultThrottleErrorCodes = map[string]struct{}{ - "Throttling": {}, - "ThrottlingException": {}, - "ThrottledException": {}, - "RequestThrottledException": {}, - "TooManyRequestsException": {}, - "ProvisionedThroughputExceededException": {}, - "TransactionInProgressException": {}, - "RequestLimitExceeded": {}, - "BandwidthLimitExceeded": {}, - "LimitExceededException": {}, - "RequestThrottled": {}, - "SlowDown": {}, - "PriorRequestNotComplete": {}, - "EC2ThrottledException": {}, -} - -// DefaultRetryables provides the set of retryable checks that are used by -// default. -var DefaultRetryables = []IsErrorRetryable{ - NoRetryCanceledError{}, - RetryableError{}, - RetryableConnectionError{}, - RetryableHTTPStatusCode{ - Codes: DefaultRetryableHTTPStatusCodes, - }, - RetryableErrorCode{ - Codes: DefaultRetryableErrorCodes, - }, - RetryableErrorCode{ - Codes: DefaultThrottleErrorCodes, - }, -} - -// DefaultTimeouts provides the set of timeout checks that are used by default. -var DefaultTimeouts = []IsErrorTimeout{ - TimeouterError{}, -} - -// StandardOptions provides the functional options for configuring the standard -// retryable, and delay behavior. -type StandardOptions struct { - // Maximum number of attempts that should be made. - MaxAttempts int - - // MaxBackoff duration between retried attempts. - MaxBackoff time.Duration - - // Provides the backoff strategy the retryer will use to determine the - // delay between retry attempts. - Backoff BackoffDelayer - - // Set of strategies to determine if the attempt should be retried based on - // the error response received. - // - // It is safe to append to this list in NewStandard's functional options. - Retryables []IsErrorRetryable - - // Set of strategies to determine if the attempt failed due to a timeout - // error. - // - // It is safe to append to this list in NewStandard's functional options. - Timeouts []IsErrorTimeout - - // Provides the rate limiting strategy for rate limiting attempt retries - // across all attempts the retryer is being used with. - // - // A RateLimiter operates as a token bucket with a set capacity, where - // attempt failures events consume tokens. A retry attempt that attempts to - // consume more tokens than what's available results in operation failure. - // The default implementation is parameterized as follows: - // - a capacity of 500 (DefaultRetryRateTokens) - // - a retry caused by a timeout costs 10 tokens (DefaultRetryCost) - // - a retry caused by other errors costs 5 tokens (DefaultRetryTimeoutCost) - // - an operation that succeeds on the 1st attempt adds 1 token (DefaultNoRetryIncrement) - // - // You can disable rate limiting by setting this field to ratelimit.None. - RateLimiter RateLimiter - - // The cost to deduct from the RateLimiter's token bucket per retry. - RetryCost uint - - // The cost to deduct from the RateLimiter's token bucket per retry caused - // by timeout error. - RetryTimeoutCost uint - - // The cost to payback to the RateLimiter's token bucket for successful - // attempts. - NoRetryIncrement uint -} - -// RateLimiter provides the interface for limiting the rate of attempt retries -// allowed by the retryer. -type RateLimiter interface { - GetToken(ctx context.Context, cost uint) (releaseToken func() error, err error) - AddTokens(uint) error -} - -// Standard is the standard retry pattern for the SDK. It uses a set of -// retryable checks to determine of the failed attempt should be retried, and -// what retry delay should be used. -type Standard struct { - options StandardOptions - - timeout IsErrorTimeout - retryable IsErrorRetryable - backoff BackoffDelayer -} - -// NewStandard initializes a standard retry behavior with defaults that can be -// overridden via functional options. -func NewStandard(fnOpts ...func(*StandardOptions)) *Standard { - o := StandardOptions{ - MaxAttempts: DefaultMaxAttempts, - MaxBackoff: DefaultMaxBackoff, - Retryables: append([]IsErrorRetryable{}, DefaultRetryables...), - Timeouts: append([]IsErrorTimeout{}, DefaultTimeouts...), - - RateLimiter: ratelimit.NewTokenRateLimit(DefaultRetryRateTokens), - RetryCost: DefaultRetryCost, - RetryTimeoutCost: DefaultRetryTimeoutCost, - NoRetryIncrement: DefaultNoRetryIncrement, - } - for _, fn := range fnOpts { - fn(&o) - } - if o.MaxAttempts <= 0 { - o.MaxAttempts = DefaultMaxAttempts - } - - backoff := o.Backoff - if backoff == nil { - backoff = NewExponentialJitterBackoff(o.MaxBackoff) - } - - return &Standard{ - options: o, - backoff: backoff, - retryable: IsErrorRetryables(o.Retryables), - timeout: IsErrorTimeouts(o.Timeouts), - } -} - -// MaxAttempts returns the maximum number of attempts that can be made for a -// request before failing. -func (s *Standard) MaxAttempts() int { - return s.options.MaxAttempts -} - -// IsErrorRetryable returns if the error is can be retried or not. Should not -// consider the number of attempts made. -func (s *Standard) IsErrorRetryable(err error) bool { - return s.retryable.IsErrorRetryable(err).Bool() -} - -// RetryDelay returns the delay to use before another request attempt is made. -func (s *Standard) RetryDelay(attempt int, err error) (time.Duration, error) { - return s.backoff.BackoffDelay(attempt, err) -} - -// GetAttemptToken returns the token to be released after then attempt completes. -// The release token will add NoRetryIncrement to the RateLimiter token pool if -// the attempt was successful. If the attempt failed, nothing will be done. -func (s *Standard) GetAttemptToken(context.Context) (func(error) error, error) { - return s.GetInitialToken(), nil -} - -// GetInitialToken returns a token for adding the NoRetryIncrement to the -// RateLimiter token if the attempt completed successfully without error. -// -// InitialToken applies to result of the each attempt, including the first. -// Whereas the RetryToken applies to the result of subsequent attempts. -// -// Deprecated: use GetAttemptToken instead. -func (s *Standard) GetInitialToken() func(error) error { - return releaseToken(s.noRetryIncrement).release -} - -func (s *Standard) noRetryIncrement() error { - return s.options.RateLimiter.AddTokens(s.options.NoRetryIncrement) -} - -// GetRetryToken attempts to deduct the retry cost from the retry token pool. -// Returning the token release function, or error. -func (s *Standard) GetRetryToken(ctx context.Context, opErr error) (func(error) error, error) { - cost := s.options.RetryCost - - if s.timeout.IsErrorTimeout(opErr).Bool() { - cost = s.options.RetryTimeoutCost - } - - fn, err := s.options.RateLimiter.GetToken(ctx, cost) - if err != nil { - return nil, fmt.Errorf("failed to get rate limit token, %w", err) - } - - return releaseToken(fn).release, nil -} - -func nopRelease(error) error { return nil } - -type releaseToken func() error - -func (f releaseToken) release(err error) error { - if err != nil { - return nil - } - - return f() -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/throttle_error.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/throttle_error.go deleted file mode 100644 index c4b844d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/throttle_error.go +++ /dev/null @@ -1,60 +0,0 @@ -package retry - -import ( - "errors" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -// IsErrorThrottle provides the interface of an implementation to determine if -// a error response from an operation is a throttling error. -type IsErrorThrottle interface { - IsErrorThrottle(error) aws.Ternary -} - -// IsErrorThrottles is a collection of checks to determine of the error a -// throttle error. Iterates through the checks and returns the state of -// throttle if any check returns something other than unknown. -type IsErrorThrottles []IsErrorThrottle - -// IsErrorThrottle returns if the error is a throttle error if any of the -// checks in the list return a value other than unknown. -func (r IsErrorThrottles) IsErrorThrottle(err error) aws.Ternary { - for _, re := range r { - if v := re.IsErrorThrottle(err); v != aws.UnknownTernary { - return v - } - } - return aws.UnknownTernary -} - -// IsErrorThrottleFunc wraps a function with the IsErrorThrottle interface. -type IsErrorThrottleFunc func(error) aws.Ternary - -// IsErrorThrottle returns if the error is a throttle error. -func (fn IsErrorThrottleFunc) IsErrorThrottle(err error) aws.Ternary { - return fn(err) -} - -// ThrottleErrorCode determines if an attempt should be retried based on the -// API error code. -type ThrottleErrorCode struct { - Codes map[string]struct{} -} - -// IsErrorThrottle return if the error is a throttle error based on the error -// codes. Returns unknown if the error doesn't have a code or it is unknown. -func (r ThrottleErrorCode) IsErrorThrottle(err error) aws.Ternary { - var v interface{ ErrorCode() string } - - if !errors.As(err, &v) { - return aws.UnknownTernary - } - - _, ok := r.Codes[v.ErrorCode()] - if !ok { - return aws.UnknownTernary - } - - return aws.TrueTernary -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/timeout_error.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/timeout_error.go deleted file mode 100644 index 3d47870..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/timeout_error.go +++ /dev/null @@ -1,52 +0,0 @@ -package retry - -import ( - "errors" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -// IsErrorTimeout provides the interface of an implementation to determine if -// a error matches. -type IsErrorTimeout interface { - IsErrorTimeout(err error) aws.Ternary -} - -// IsErrorTimeouts is a collection of checks to determine of the error is -// retryable. Iterates through the checks and returns the state of retryable -// if any check returns something other than unknown. -type IsErrorTimeouts []IsErrorTimeout - -// IsErrorTimeout returns if the error is retryable if any of the checks in -// the list return a value other than unknown. -func (ts IsErrorTimeouts) IsErrorTimeout(err error) aws.Ternary { - for _, t := range ts { - if v := t.IsErrorTimeout(err); v != aws.UnknownTernary { - return v - } - } - return aws.UnknownTernary -} - -// IsErrorTimeoutFunc wraps a function with the IsErrorTimeout interface. -type IsErrorTimeoutFunc func(error) aws.Ternary - -// IsErrorTimeout returns if the error is retryable. -func (fn IsErrorTimeoutFunc) IsErrorTimeout(err error) aws.Ternary { - return fn(err) -} - -// TimeouterError provides the IsErrorTimeout implementation for determining if -// an error is a timeout based on type with the Timeout method. -type TimeouterError struct{} - -// IsErrorTimeout returns if the error is a timeout error. -func (t TimeouterError) IsErrorTimeout(err error) aws.Ternary { - var v interface{ Timeout() bool } - - if !errors.As(err, &v) { - return aws.UnknownTernary - } - - return aws.BoolTernary(v.Timeout()) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retryer.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retryer.go deleted file mode 100644 index b0ba4cb..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retryer.go +++ /dev/null @@ -1,127 +0,0 @@ -package aws - -import ( - "context" - "fmt" - "time" -) - -// RetryMode provides the mode the API client will use to create a retryer -// based on. -type RetryMode string - -const ( - // RetryModeStandard model provides rate limited retry attempts with - // exponential backoff delay. - RetryModeStandard RetryMode = "standard" - - // RetryModeAdaptive model provides attempt send rate limiting on throttle - // responses in addition to standard mode's retry rate limiting. - // - // Adaptive retry mode is experimental and is subject to change in the - // future. - RetryModeAdaptive RetryMode = "adaptive" -) - -// ParseRetryMode attempts to parse a RetryMode from the given string. -// Returning error if the value is not a known RetryMode. -func ParseRetryMode(v string) (mode RetryMode, err error) { - switch v { - case "standard": - return RetryModeStandard, nil - case "adaptive": - return RetryModeAdaptive, nil - default: - return mode, fmt.Errorf("unknown RetryMode, %v", v) - } -} - -func (m RetryMode) String() string { return string(m) } - -// Retryer is an interface to determine if a given error from a -// attempt should be retried, and if so what backoff delay to apply. The -// default implementation used by most services is the retry package's Standard -// type. Which contains basic retry logic using exponential backoff. -type Retryer interface { - // IsErrorRetryable returns if the failed attempt is retryable. This check - // should determine if the error can be retried, or if the error is - // terminal. - IsErrorRetryable(error) bool - - // MaxAttempts returns the maximum number of attempts that can be made for - // an attempt before failing. A value of 0 implies that the attempt should - // be retried until it succeeds if the errors are retryable. - MaxAttempts() int - - // RetryDelay returns the delay that should be used before retrying the - // attempt. Will return error if the delay could not be determined. - RetryDelay(attempt int, opErr error) (time.Duration, error) - - // GetRetryToken attempts to deduct the retry cost from the retry token pool. - // Returning the token release function, or error. - GetRetryToken(ctx context.Context, opErr error) (releaseToken func(error) error, err error) - - // GetInitialToken returns the initial attempt token that can increment the - // retry token pool if the attempt is successful. - GetInitialToken() (releaseToken func(error) error) -} - -// RetryerV2 is an interface to determine if a given error from an attempt -// should be retried, and if so what backoff delay to apply. The default -// implementation used by most services is the retry package's Standard type. -// Which contains basic retry logic using exponential backoff. -// -// RetryerV2 replaces the Retryer interface, deprecating the GetInitialToken -// method in favor of GetAttemptToken which takes a context, and can return an error. -// -// The SDK's retry package's Attempt middleware, and utilities will always -// wrap a Retryer as a RetryerV2. Delegating to GetInitialToken, only if -// GetAttemptToken is not implemented. -type RetryerV2 interface { - Retryer - - // GetInitialToken returns the initial attempt token that can increment the - // retry token pool if the attempt is successful. - // - // Deprecated: This method does not provide a way to block using Context, - // nor can it return an error. Use RetryerV2, and GetAttemptToken instead. - GetInitialToken() (releaseToken func(error) error) - - // GetAttemptToken returns the send token that can be used to rate limit - // attempt calls. Will be used by the SDK's retry package's Attempt - // middleware to get a send token prior to calling the temp and releasing - // the send token after the attempt has been made. - GetAttemptToken(context.Context) (func(error) error, error) -} - -// NopRetryer provides a RequestRetryDecider implementation that will flag -// all attempt errors as not retryable, with a max attempts of 1. -type NopRetryer struct{} - -// IsErrorRetryable returns false for all error values. -func (NopRetryer) IsErrorRetryable(error) bool { return false } - -// MaxAttempts always returns 1 for the original attempt. -func (NopRetryer) MaxAttempts() int { return 1 } - -// RetryDelay is not valid for the NopRetryer. Will always return error. -func (NopRetryer) RetryDelay(int, error) (time.Duration, error) { - return 0, fmt.Errorf("not retrying any attempt errors") -} - -// GetRetryToken returns a stub function that does nothing. -func (NopRetryer) GetRetryToken(context.Context, error) (func(error) error, error) { - return nopReleaseToken, nil -} - -// GetInitialToken returns a stub function that does nothing. -func (NopRetryer) GetInitialToken() func(error) error { - return nopReleaseToken -} - -// GetAttemptToken returns a stub function that does nothing. -func (NopRetryer) GetAttemptToken(context.Context) (func(error) error, error) { - return nopReleaseToken, nil -} - -func nopReleaseToken(error) error { return nil } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/runtime.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/runtime.go deleted file mode 100644 index 3af9b2b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/runtime.go +++ /dev/null @@ -1,14 +0,0 @@ -package aws - -// ExecutionEnvironmentID is the AWS execution environment runtime identifier. -type ExecutionEnvironmentID string - -// RuntimeEnvironment is a collection of values that are determined at runtime -// based on the environment that the SDK is executing in. Some of these values -// may or may not be present based on the executing environment and certain SDK -// configuration properties that drive whether these values are populated.. -type RuntimeEnvironment struct { - EnvironmentIdentifier ExecutionEnvironmentID - Region string - EC2InstanceMetadataRegion string -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/cache.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/cache.go deleted file mode 100644 index cbf22f1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/cache.go +++ /dev/null @@ -1,115 +0,0 @@ -package v4 - -import ( - "strings" - "sync" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -func lookupKey(service, region string) string { - var s strings.Builder - s.Grow(len(region) + len(service) + 3) - s.WriteString(region) - s.WriteRune('/') - s.WriteString(service) - return s.String() -} - -type derivedKey struct { - AccessKey string - Date time.Time - Credential []byte -} - -type derivedKeyCache struct { - values map[string]derivedKey - mutex sync.RWMutex -} - -func newDerivedKeyCache() derivedKeyCache { - return derivedKeyCache{ - values: make(map[string]derivedKey), - } -} - -func (s *derivedKeyCache) Get(credentials aws.Credentials, service, region string, signingTime SigningTime) []byte { - key := lookupKey(service, region) - s.mutex.RLock() - if cred, ok := s.get(key, credentials, signingTime.Time); ok { - s.mutex.RUnlock() - return cred - } - s.mutex.RUnlock() - - s.mutex.Lock() - if cred, ok := s.get(key, credentials, signingTime.Time); ok { - s.mutex.Unlock() - return cred - } - cred := deriveKey(credentials.SecretAccessKey, service, region, signingTime) - entry := derivedKey{ - AccessKey: credentials.AccessKeyID, - Date: signingTime.Time, - Credential: cred, - } - s.values[key] = entry - s.mutex.Unlock() - - return cred -} - -func (s *derivedKeyCache) get(key string, credentials aws.Credentials, signingTime time.Time) ([]byte, bool) { - cacheEntry, ok := s.retrieveFromCache(key) - if ok && cacheEntry.AccessKey == credentials.AccessKeyID && isSameDay(signingTime, cacheEntry.Date) { - return cacheEntry.Credential, true - } - return nil, false -} - -func (s *derivedKeyCache) retrieveFromCache(key string) (derivedKey, bool) { - if v, ok := s.values[key]; ok { - return v, true - } - return derivedKey{}, false -} - -// SigningKeyDeriver derives a signing key from a set of credentials -type SigningKeyDeriver struct { - cache derivedKeyCache -} - -// NewSigningKeyDeriver returns a new SigningKeyDeriver -func NewSigningKeyDeriver() *SigningKeyDeriver { - return &SigningKeyDeriver{ - cache: newDerivedKeyCache(), - } -} - -// DeriveKey returns a derived signing key from the given credentials to be used with SigV4 signing. -func (k *SigningKeyDeriver) DeriveKey(credential aws.Credentials, service, region string, signingTime SigningTime) []byte { - return k.cache.Get(credential, service, region, signingTime) -} - -func deriveKey(secret, service, region string, t SigningTime) []byte { - hmacDate := HMACSHA256([]byte("AWS4"+secret), []byte(t.ShortTimeFormat())) - hmacRegion := HMACSHA256(hmacDate, []byte(region)) - hmacService := HMACSHA256(hmacRegion, []byte(service)) - return HMACSHA256(hmacService, []byte("aws4_request")) -} - -func isSameDay(x, y time.Time) bool { - xYear, xMonth, xDay := x.Date() - yYear, yMonth, yDay := y.Date() - - if xYear != yYear { - return false - } - - if xMonth != yMonth { - return false - } - - return xDay == yDay -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/const.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/const.go deleted file mode 100644 index a23cb00..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/const.go +++ /dev/null @@ -1,40 +0,0 @@ -package v4 - -// Signature Version 4 (SigV4) Constants -const ( - // EmptyStringSHA256 is the hex encoded sha256 value of an empty string - EmptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` - - // UnsignedPayload indicates that the request payload body is unsigned - UnsignedPayload = "UNSIGNED-PAYLOAD" - - // AmzAlgorithmKey indicates the signing algorithm - AmzAlgorithmKey = "X-Amz-Algorithm" - - // AmzSecurityTokenKey indicates the security token to be used with temporary credentials - AmzSecurityTokenKey = "X-Amz-Security-Token" - - // AmzDateKey is the UTC timestamp for the request in the format YYYYMMDD'T'HHMMSS'Z' - AmzDateKey = "X-Amz-Date" - - // AmzCredentialKey is the access key ID and credential scope - AmzCredentialKey = "X-Amz-Credential" - - // AmzSignedHeadersKey is the set of headers signed for the request - AmzSignedHeadersKey = "X-Amz-SignedHeaders" - - // AmzSignatureKey is the query parameter to store the SigV4 signature - AmzSignatureKey = "X-Amz-Signature" - - // TimeFormat is the time format to be used in the X-Amz-Date header or query parameter - TimeFormat = "20060102T150405Z" - - // ShortTimeFormat is the shorten time format used in the credential scope - ShortTimeFormat = "20060102" - - // ContentSHAKey is the SHA256 of request body - ContentSHAKey = "X-Amz-Content-Sha256" - - // StreamingEventsPayload indicates that the request payload body is a signed event stream. - StreamingEventsPayload = "STREAMING-AWS4-HMAC-SHA256-EVENTS" -) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/header_rules.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/header_rules.go deleted file mode 100644 index c61955a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/header_rules.go +++ /dev/null @@ -1,82 +0,0 @@ -package v4 - -import ( - sdkstrings "github.com/aws/aws-sdk-go-v2/internal/strings" -) - -// Rules houses a set of Rule needed for validation of a -// string value -type Rules []Rule - -// Rule interface allows for more flexible rules and just simply -// checks whether or not a value adheres to that Rule -type Rule interface { - IsValid(value string) bool -} - -// IsValid will iterate through all rules and see if any rules -// apply to the value and supports nested rules -func (r Rules) IsValid(value string) bool { - for _, rule := range r { - if rule.IsValid(value) { - return true - } - } - return false -} - -// MapRule generic Rule for maps -type MapRule map[string]struct{} - -// IsValid for the map Rule satisfies whether it exists in the map -func (m MapRule) IsValid(value string) bool { - _, ok := m[value] - return ok -} - -// AllowList is a generic Rule for include listing -type AllowList struct { - Rule -} - -// IsValid for AllowList checks if the value is within the AllowList -func (w AllowList) IsValid(value string) bool { - return w.Rule.IsValid(value) -} - -// ExcludeList is a generic Rule for exclude listing -type ExcludeList struct { - Rule -} - -// IsValid for AllowList checks if the value is within the AllowList -func (b ExcludeList) IsValid(value string) bool { - return !b.Rule.IsValid(value) -} - -// Patterns is a list of strings to match against -type Patterns []string - -// IsValid for Patterns checks each pattern and returns if a match has -// been found -func (p Patterns) IsValid(value string) bool { - for _, pattern := range p { - if sdkstrings.HasPrefixFold(value, pattern) { - return true - } - } - return false -} - -// InclusiveRules rules allow for rules to depend on one another -type InclusiveRules []Rule - -// IsValid will return true if all rules are true -func (r InclusiveRules) IsValid(value string) bool { - for _, rule := range r { - if !rule.IsValid(value) { - return false - } - } - return true -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go deleted file mode 100644 index d99b32c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go +++ /dev/null @@ -1,70 +0,0 @@ -package v4 - -// IgnoredHeaders is a list of headers that are ignored during signing -var IgnoredHeaders = Rules{ - ExcludeList{ - MapRule{ - "Authorization": struct{}{}, - "User-Agent": struct{}{}, - "X-Amzn-Trace-Id": struct{}{}, - "Expect": struct{}{}, - "Transfer-Encoding": struct{}{}, - }, - }, -} - -// RequiredSignedHeaders is a allow list for Build canonical headers. -var RequiredSignedHeaders = Rules{ - AllowList{ - MapRule{ - "Cache-Control": struct{}{}, - "Content-Disposition": struct{}{}, - "Content-Encoding": struct{}{}, - "Content-Language": struct{}{}, - "Content-Md5": struct{}{}, - "Content-Type": struct{}{}, - "Expires": struct{}{}, - "If-Match": struct{}{}, - "If-Modified-Since": struct{}{}, - "If-None-Match": struct{}{}, - "If-Unmodified-Since": struct{}{}, - "Range": struct{}{}, - "X-Amz-Acl": struct{}{}, - "X-Amz-Copy-Source": struct{}{}, - "X-Amz-Copy-Source-If-Match": struct{}{}, - "X-Amz-Copy-Source-If-Modified-Since": struct{}{}, - "X-Amz-Copy-Source-If-None-Match": struct{}{}, - "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{}, - "X-Amz-Copy-Source-Range": struct{}{}, - "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{}, - "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{}, - "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, - "X-Amz-Grant-Full-control": struct{}{}, - "X-Amz-Grant-Read": struct{}{}, - "X-Amz-Grant-Read-Acp": struct{}{}, - "X-Amz-Grant-Write": struct{}{}, - "X-Amz-Grant-Write-Acp": struct{}{}, - "X-Amz-Metadata-Directive": struct{}{}, - "X-Amz-Mfa": struct{}{}, - "X-Amz-Server-Side-Encryption": struct{}{}, - "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{}, - "X-Amz-Server-Side-Encryption-Context": struct{}{}, - "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{}, - "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{}, - "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, - "X-Amz-Storage-Class": struct{}{}, - "X-Amz-Website-Redirect-Location": struct{}{}, - "X-Amz-Content-Sha256": struct{}{}, - "X-Amz-Tagging": struct{}{}, - }, - }, - Patterns{"X-Amz-Object-Lock-"}, - Patterns{"X-Amz-Meta-"}, -} - -// AllowedQueryHoisting is a allowed list for Build query headers. The boolean value -// represents whether or not it is a pattern. -var AllowedQueryHoisting = InclusiveRules{ - ExcludeList{RequiredSignedHeaders}, - Patterns{"X-Amz-"}, -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/hmac.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/hmac.go deleted file mode 100644 index e7fa7a1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/hmac.go +++ /dev/null @@ -1,13 +0,0 @@ -package v4 - -import ( - "crypto/hmac" - "crypto/sha256" -) - -// HMACSHA256 computes a HMAC-SHA256 of data given the provided key. -func HMACSHA256(key []byte, data []byte) []byte { - hash := hmac.New(sha256.New, key) - hash.Write(data) - return hash.Sum(nil) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/host.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/host.go deleted file mode 100644 index bf93659..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/host.go +++ /dev/null @@ -1,75 +0,0 @@ -package v4 - -import ( - "net/http" - "strings" -) - -// SanitizeHostForHeader removes default port from host and updates request.Host -func SanitizeHostForHeader(r *http.Request) { - host := getHost(r) - port := portOnly(host) - if port != "" && isDefaultPort(r.URL.Scheme, port) { - r.Host = stripPort(host) - } -} - -// Returns host from request -func getHost(r *http.Request) string { - if r.Host != "" { - return r.Host - } - - return r.URL.Host -} - -// Hostname returns u.Host, without any port number. -// -// If Host is an IPv6 literal with a port number, Hostname returns the -// IPv6 literal without the square brackets. IPv6 literals may include -// a zone identifier. -// -// Copied from the Go 1.8 standard library (net/url) -func stripPort(hostport string) string { - colon := strings.IndexByte(hostport, ':') - if colon == -1 { - return hostport - } - if i := strings.IndexByte(hostport, ']'); i != -1 { - return strings.TrimPrefix(hostport[:i], "[") - } - return hostport[:colon] -} - -// Port returns the port part of u.Host, without the leading colon. -// If u.Host doesn't contain a port, Port returns an empty string. -// -// Copied from the Go 1.8 standard library (net/url) -func portOnly(hostport string) string { - colon := strings.IndexByte(hostport, ':') - if colon == -1 { - return "" - } - if i := strings.Index(hostport, "]:"); i != -1 { - return hostport[i+len("]:"):] - } - if strings.Contains(hostport, "]") { - return "" - } - return hostport[colon+len(":"):] -} - -// Returns true if the specified URI is using the standard port -// (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs) -func isDefaultPort(scheme, port string) bool { - if port == "" { - return true - } - - lowerCaseScheme := strings.ToLower(scheme) - if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") { - return true - } - - return false -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/scope.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/scope.go deleted file mode 100644 index fc78879..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/scope.go +++ /dev/null @@ -1,13 +0,0 @@ -package v4 - -import "strings" - -// BuildCredentialScope builds the Signature Version 4 (SigV4) signing scope -func BuildCredentialScope(signingTime SigningTime, region, service string) string { - return strings.Join([]string{ - signingTime.ShortTimeFormat(), - region, - service, - "aws4_request", - }, "/") -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/time.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/time.go deleted file mode 100644 index 1de06a7..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/time.go +++ /dev/null @@ -1,36 +0,0 @@ -package v4 - -import "time" - -// SigningTime provides a wrapper around a time.Time which provides cached values for SigV4 signing. -type SigningTime struct { - time.Time - timeFormat string - shortTimeFormat string -} - -// NewSigningTime creates a new SigningTime given a time.Time -func NewSigningTime(t time.Time) SigningTime { - return SigningTime{ - Time: t, - } -} - -// TimeFormat provides a time formatted in the X-Amz-Date format. -func (m *SigningTime) TimeFormat() string { - return m.format(&m.timeFormat, TimeFormat) -} - -// ShortTimeFormat provides a time formatted of 20060102. -func (m *SigningTime) ShortTimeFormat() string { - return m.format(&m.shortTimeFormat, ShortTimeFormat) -} - -func (m *SigningTime) format(target *string, format string) string { - if len(*target) > 0 { - return *target - } - v := m.Time.Format(format) - *target = v - return v -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/util.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/util.go deleted file mode 100644 index d025dba..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/util.go +++ /dev/null @@ -1,80 +0,0 @@ -package v4 - -import ( - "net/url" - "strings" -) - -const doubleSpace = " " - -// StripExcessSpaces will rewrite the passed in slice's string values to not -// contain multiple side-by-side spaces. -func StripExcessSpaces(str string) string { - var j, k, l, m, spaces int - // Trim trailing spaces - for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- { - } - - // Trim leading spaces - for k = 0; k < j && str[k] == ' '; k++ { - } - str = str[k : j+1] - - // Strip multiple spaces. - j = strings.Index(str, doubleSpace) - if j < 0 { - return str - } - - buf := []byte(str) - for k, m, l = j, j, len(buf); k < l; k++ { - if buf[k] == ' ' { - if spaces == 0 { - // First space. - buf[m] = buf[k] - m++ - } - spaces++ - } else { - // End of multiple spaces. - spaces = 0 - buf[m] = buf[k] - m++ - } - } - - return string(buf[:m]) -} - -// GetURIPath returns the escaped URI component from the provided URL. -func GetURIPath(u *url.URL) string { - var uriPath string - - if len(u.Opaque) > 0 { - const schemeSep, pathSep, queryStart = "//", "/", "?" - - opaque := u.Opaque - // Cut off the query string if present. - if idx := strings.Index(opaque, queryStart); idx >= 0 { - opaque = opaque[:idx] - } - - // Cutout the scheme separator if present. - if strings.Index(opaque, schemeSep) == 0 { - opaque = opaque[len(schemeSep):] - } - - // capture URI path starting with first path separator. - if idx := strings.Index(opaque, pathSep); idx >= 0 { - uriPath = opaque[idx:] - } - } else { - uriPath = u.EscapedPath() - } - - if len(uriPath) == 0 { - uriPath = "/" - } - - return uriPath -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/middleware.go deleted file mode 100644 index 8a46220..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/middleware.go +++ /dev/null @@ -1,420 +0,0 @@ -package v4 - -import ( - "context" - "crypto/sha256" - "encoding/hex" - "fmt" - "io" - "net/http" - "strings" - - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - v4Internal "github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4" - internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -const computePayloadHashMiddlewareID = "ComputePayloadHash" - -// HashComputationError indicates an error occurred while computing the signing hash -type HashComputationError struct { - Err error -} - -// Error is the error message -func (e *HashComputationError) Error() string { - return fmt.Sprintf("failed to compute payload hash: %v", e.Err) -} - -// Unwrap returns the underlying error if one is set -func (e *HashComputationError) Unwrap() error { - return e.Err -} - -// SigningError indicates an error condition occurred while performing SigV4 signing -type SigningError struct { - Err error -} - -func (e *SigningError) Error() string { - return fmt.Sprintf("failed to sign request: %v", e.Err) -} - -// Unwrap returns the underlying error cause -func (e *SigningError) Unwrap() error { - return e.Err -} - -// UseDynamicPayloadSigningMiddleware swaps the compute payload sha256 middleware with a resolver middleware that -// switches between unsigned and signed payload based on TLS state for request. -// This middleware should not be used for AWS APIs that do not support unsigned payload signing auth. -// By default, SDK uses this middleware for known AWS APIs that support such TLS based auth selection . -// -// Usage example - -// S3 PutObject API allows unsigned payload signing auth usage when TLS is enabled, and uses this middleware to -// dynamically switch between unsigned and signed payload based on TLS state for request. -func UseDynamicPayloadSigningMiddleware(stack *middleware.Stack) error { - _, err := stack.Finalize.Swap(computePayloadHashMiddlewareID, &dynamicPayloadSigningMiddleware{}) - return err -} - -// dynamicPayloadSigningMiddleware dynamically resolves the middleware that computes and set payload sha256 middleware. -type dynamicPayloadSigningMiddleware struct { -} - -// ID returns the resolver identifier -func (m *dynamicPayloadSigningMiddleware) ID() string { - return computePayloadHashMiddlewareID -} - -// HandleFinalize delegates SHA256 computation according to whether the request -// is TLS-enabled. -func (m *dynamicPayloadSigningMiddleware) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if req.IsHTTPS() { - return (&UnsignedPayload{}).HandleFinalize(ctx, in, next) - } - return (&ComputePayloadSHA256{}).HandleFinalize(ctx, in, next) -} - -// UnsignedPayload sets the SigV4 request payload hash to unsigned. -// -// Will not set the Unsigned Payload magic SHA value, if a SHA has already been -// stored in the context. (e.g. application pre-computed SHA256 before making -// API call). -// -// This middleware does not check the X-Amz-Content-Sha256 header, if that -// header is serialized a middleware must translate it into the context. -type UnsignedPayload struct{} - -// AddUnsignedPayloadMiddleware adds unsignedPayload to the operation -// middleware stack -func AddUnsignedPayloadMiddleware(stack *middleware.Stack) error { - return stack.Finalize.Insert(&UnsignedPayload{}, "ResolveEndpointV2", middleware.After) -} - -// ID returns the unsignedPayload identifier -func (m *UnsignedPayload) ID() string { - return computePayloadHashMiddlewareID -} - -// HandleFinalize sets the payload hash magic value to the unsigned sentinel. -func (m *UnsignedPayload) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - if GetPayloadHash(ctx) == "" { - ctx = SetPayloadHash(ctx, v4Internal.UnsignedPayload) - } - return next.HandleFinalize(ctx, in) -} - -// ComputePayloadSHA256 computes SHA256 payload hash to sign. -// -// Will not set the Unsigned Payload magic SHA value, if a SHA has already been -// stored in the context. (e.g. application pre-computed SHA256 before making -// API call). -// -// This middleware does not check the X-Amz-Content-Sha256 header, if that -// header is serialized a middleware must translate it into the context. -type ComputePayloadSHA256 struct{} - -// AddComputePayloadSHA256Middleware adds computePayloadSHA256 to the -// operation middleware stack -func AddComputePayloadSHA256Middleware(stack *middleware.Stack) error { - return stack.Finalize.Insert(&ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After) -} - -// RemoveComputePayloadSHA256Middleware removes computePayloadSHA256 from the -// operation middleware stack -func RemoveComputePayloadSHA256Middleware(stack *middleware.Stack) error { - _, err := stack.Finalize.Remove(computePayloadHashMiddlewareID) - return err -} - -// ID is the middleware name -func (m *ComputePayloadSHA256) ID() string { - return computePayloadHashMiddlewareID -} - -// HandleFinalize computes the payload hash for the request, storing it to the -// context. This is a no-op if a caller has previously set that value. -func (m *ComputePayloadSHA256) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - if GetPayloadHash(ctx) != "" { - return next.HandleFinalize(ctx, in) - } - - _, span := tracing.StartSpan(ctx, "ComputePayloadSHA256") - defer span.End() - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &HashComputationError{ - Err: fmt.Errorf("unexpected request middleware type %T", in.Request), - } - } - - hash := sha256.New() - if stream := req.GetStream(); stream != nil { - _, err = io.Copy(hash, stream) - if err != nil { - return out, metadata, &HashComputationError{ - Err: fmt.Errorf("failed to compute payload hash, %w", err), - } - } - - if err := req.RewindStream(); err != nil { - return out, metadata, &HashComputationError{ - Err: fmt.Errorf("failed to seek body to start, %w", err), - } - } - } - - ctx = SetPayloadHash(ctx, hex.EncodeToString(hash.Sum(nil))) - - span.End() - return next.HandleFinalize(ctx, in) -} - -// SwapComputePayloadSHA256ForUnsignedPayloadMiddleware replaces the -// ComputePayloadSHA256 middleware with the UnsignedPayload middleware. -// -// Use this to disable computing the Payload SHA256 checksum and instead use -// UNSIGNED-PAYLOAD for the SHA256 value. -func SwapComputePayloadSHA256ForUnsignedPayloadMiddleware(stack *middleware.Stack) error { - _, err := stack.Finalize.Swap(computePayloadHashMiddlewareID, &UnsignedPayload{}) - return err -} - -// ContentSHA256Header sets the X-Amz-Content-Sha256 header value to -// the Payload hash stored in the context. -type ContentSHA256Header struct{} - -// AddContentSHA256HeaderMiddleware adds ContentSHA256Header to the -// operation middleware stack -func AddContentSHA256HeaderMiddleware(stack *middleware.Stack) error { - return stack.Finalize.Insert(&ContentSHA256Header{}, computePayloadHashMiddlewareID, middleware.After) -} - -// RemoveContentSHA256HeaderMiddleware removes contentSHA256Header middleware -// from the operation middleware stack -func RemoveContentSHA256HeaderMiddleware(stack *middleware.Stack) error { - _, err := stack.Finalize.Remove((*ContentSHA256Header)(nil).ID()) - return err -} - -// ID returns the ContentSHA256HeaderMiddleware identifier -func (m *ContentSHA256Header) ID() string { - return "SigV4ContentSHA256Header" -} - -// HandleFinalize sets the X-Amz-Content-Sha256 header value to the Payload hash -// stored in the context. -func (m *ContentSHA256Header) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &HashComputationError{Err: fmt.Errorf("unexpected request middleware type %T", in.Request)} - } - - req.Header.Set(v4Internal.ContentSHAKey, GetPayloadHash(ctx)) - return next.HandleFinalize(ctx, in) -} - -// SignHTTPRequestMiddlewareOptions is the configuration options for -// [SignHTTPRequestMiddleware]. -// -// Deprecated: [SignHTTPRequestMiddleware] is deprecated. -type SignHTTPRequestMiddlewareOptions struct { - CredentialsProvider aws.CredentialsProvider - Signer HTTPSigner - LogSigning bool -} - -// SignHTTPRequestMiddleware is a `FinalizeMiddleware` implementation for SigV4 -// HTTP Signing. -// -// Deprecated: AWS service clients no longer use this middleware. Signing as an -// SDK operation is now performed through an internal per-service middleware -// which opaquely selects and uses the signer from the resolved auth scheme. -type SignHTTPRequestMiddleware struct { - credentialsProvider aws.CredentialsProvider - signer HTTPSigner - logSigning bool -} - -// NewSignHTTPRequestMiddleware constructs a [SignHTTPRequestMiddleware] using -// the given [Signer] for signing requests. -// -// Deprecated: SignHTTPRequestMiddleware is deprecated. -func NewSignHTTPRequestMiddleware(options SignHTTPRequestMiddlewareOptions) *SignHTTPRequestMiddleware { - return &SignHTTPRequestMiddleware{ - credentialsProvider: options.CredentialsProvider, - signer: options.Signer, - logSigning: options.LogSigning, - } -} - -// ID is the SignHTTPRequestMiddleware identifier. -// -// Deprecated: SignHTTPRequestMiddleware is deprecated. -func (s *SignHTTPRequestMiddleware) ID() string { - return "Signing" -} - -// HandleFinalize will take the provided input and sign the request using the -// SigV4 authentication scheme. -// -// Deprecated: SignHTTPRequestMiddleware is deprecated. -func (s *SignHTTPRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - if !haveCredentialProvider(s.credentialsProvider) { - return next.HandleFinalize(ctx, in) - } - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &SigningError{Err: fmt.Errorf("unexpected request middleware type %T", in.Request)} - } - - signingName, signingRegion := awsmiddleware.GetSigningName(ctx), awsmiddleware.GetSigningRegion(ctx) - payloadHash := GetPayloadHash(ctx) - if len(payloadHash) == 0 { - return out, metadata, &SigningError{Err: fmt.Errorf("computed payload hash missing from context")} - } - - credentials, err := s.credentialsProvider.Retrieve(ctx) - if err != nil { - return out, metadata, &SigningError{Err: fmt.Errorf("failed to retrieve credentials: %w", err)} - } - - signerOptions := []func(o *SignerOptions){ - func(o *SignerOptions) { - o.Logger = middleware.GetLogger(ctx) - o.LogSigning = s.logSigning - }, - } - - // existing DisableURIPathEscaping is equivalent in purpose - // to authentication scheme property DisableDoubleEncoding - disableDoubleEncoding, overridden := internalauth.GetDisableDoubleEncoding(ctx) - if overridden { - signerOptions = append(signerOptions, func(o *SignerOptions) { - o.DisableURIPathEscaping = disableDoubleEncoding - }) - } - - err = s.signer.SignHTTP(ctx, credentials, req.Request, payloadHash, signingName, signingRegion, sdk.NowTime(), signerOptions...) - if err != nil { - return out, metadata, &SigningError{Err: fmt.Errorf("failed to sign http request, %w", err)} - } - - ctx = awsmiddleware.SetSigningCredentials(ctx, credentials) - - return next.HandleFinalize(ctx, in) -} - -// StreamingEventsPayload signs input event stream messages. -type StreamingEventsPayload struct{} - -// AddStreamingEventsPayload adds the streamingEventsPayload middleware to the stack. -func AddStreamingEventsPayload(stack *middleware.Stack) error { - return stack.Finalize.Add(&StreamingEventsPayload{}, middleware.Before) -} - -// ID identifies the middleware. -func (s *StreamingEventsPayload) ID() string { - return computePayloadHashMiddlewareID -} - -// HandleFinalize marks the input stream to be signed with SigV4. -func (s *StreamingEventsPayload) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - contentSHA := GetPayloadHash(ctx) - if len(contentSHA) == 0 { - contentSHA = v4Internal.StreamingEventsPayload - } - - ctx = SetPayloadHash(ctx, contentSHA) - - return next.HandleFinalize(ctx, in) -} - -// GetSignedRequestSignature attempts to extract the signature of the request. -// Returning an error if the request is unsigned, or unable to extract the -// signature. -func GetSignedRequestSignature(r *http.Request) ([]byte, error) { - const authHeaderSignatureElem = "Signature=" - - if auth := r.Header.Get(authorizationHeader); len(auth) != 0 { - ps := strings.Split(auth, ",") - for _, p := range ps { - p = strings.TrimSpace(p) - if idx := strings.Index(p, authHeaderSignatureElem); idx >= 0 { - sig := p[len(authHeaderSignatureElem):] - if len(sig) == 0 { - return nil, fmt.Errorf("invalid request signature authorization header") - } - return hex.DecodeString(sig) - } - } - } - - if sig := r.URL.Query().Get("X-Amz-Signature"); len(sig) != 0 { - return hex.DecodeString(sig) - } - - return nil, fmt.Errorf("request not signed") -} - -func haveCredentialProvider(p aws.CredentialsProvider) bool { - if p == nil { - return false - } - - return !aws.IsCredentialsProvider(p, (*aws.AnonymousCredentials)(nil)) -} - -type payloadHashKey struct{} - -// GetPayloadHash retrieves the payload hash to use for signing -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func GetPayloadHash(ctx context.Context) (v string) { - v, _ = middleware.GetStackValue(ctx, payloadHashKey{}).(string) - return v -} - -// SetPayloadHash sets the payload hash to be used for signing the request -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func SetPayloadHash(ctx context.Context, hash string) context.Context { - return middleware.WithStackValue(ctx, payloadHashKey{}, hash) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/presign_middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/presign_middleware.go deleted file mode 100644 index e1a0665..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/presign_middleware.go +++ /dev/null @@ -1,127 +0,0 @@ -package v4 - -import ( - "context" - "fmt" - "net/http" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/smithy-go/middleware" - smithyHTTP "github.com/aws/smithy-go/transport/http" -) - -// HTTPPresigner is an interface to a SigV4 signer that can sign create a -// presigned URL for a HTTP requests. -type HTTPPresigner interface { - PresignHTTP( - ctx context.Context, credentials aws.Credentials, r *http.Request, - payloadHash string, service string, region string, signingTime time.Time, - optFns ...func(*SignerOptions), - ) (url string, signedHeader http.Header, err error) -} - -// PresignedHTTPRequest provides the URL and signed headers that are included -// in the presigned URL. -type PresignedHTTPRequest struct { - URL string - Method string - SignedHeader http.Header -} - -// PresignHTTPRequestMiddlewareOptions is the options for the PresignHTTPRequestMiddleware middleware. -type PresignHTTPRequestMiddlewareOptions struct { - CredentialsProvider aws.CredentialsProvider - Presigner HTTPPresigner - LogSigning bool -} - -// PresignHTTPRequestMiddleware provides the Finalize middleware for creating a -// presigned URL for an HTTP request. -// -// Will short circuit the middleware stack and not forward onto the next -// Finalize handler. -type PresignHTTPRequestMiddleware struct { - credentialsProvider aws.CredentialsProvider - presigner HTTPPresigner - logSigning bool -} - -// NewPresignHTTPRequestMiddleware returns a new PresignHTTPRequestMiddleware -// initialized with the presigner. -func NewPresignHTTPRequestMiddleware(options PresignHTTPRequestMiddlewareOptions) *PresignHTTPRequestMiddleware { - return &PresignHTTPRequestMiddleware{ - credentialsProvider: options.CredentialsProvider, - presigner: options.Presigner, - logSigning: options.LogSigning, - } -} - -// ID provides the middleware ID. -func (*PresignHTTPRequestMiddleware) ID() string { return "PresignHTTPRequest" } - -// HandleFinalize will take the provided input and create a presigned url for -// the http request using the SigV4 presign authentication scheme. -// -// Since the signed request is not a valid HTTP request -func (s *PresignHTTPRequestMiddleware) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyHTTP.Request) - if !ok { - return out, metadata, &SigningError{ - Err: fmt.Errorf("unexpected request middleware type %T", in.Request), - } - } - - httpReq := req.Build(ctx) - if !haveCredentialProvider(s.credentialsProvider) { - out.Result = &PresignedHTTPRequest{ - URL: httpReq.URL.String(), - Method: httpReq.Method, - SignedHeader: http.Header{}, - } - - return out, metadata, nil - } - - signingName := awsmiddleware.GetSigningName(ctx) - signingRegion := awsmiddleware.GetSigningRegion(ctx) - payloadHash := GetPayloadHash(ctx) - if len(payloadHash) == 0 { - return out, metadata, &SigningError{ - Err: fmt.Errorf("computed payload hash missing from context"), - } - } - - credentials, err := s.credentialsProvider.Retrieve(ctx) - if err != nil { - return out, metadata, &SigningError{ - Err: fmt.Errorf("failed to retrieve credentials: %w", err), - } - } - - u, h, err := s.presigner.PresignHTTP(ctx, credentials, - httpReq, payloadHash, signingName, signingRegion, sdk.NowTime(), - func(o *SignerOptions) { - o.Logger = middleware.GetLogger(ctx) - o.LogSigning = s.logSigning - }) - if err != nil { - return out, metadata, &SigningError{ - Err: fmt.Errorf("failed to sign http request, %w", err), - } - } - - out.Result = &PresignedHTTPRequest{ - URL: u, - Method: httpReq.Method, - SignedHeader: h, - } - - return out, metadata, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/stream.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/stream.go deleted file mode 100644 index 32875e0..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/stream.go +++ /dev/null @@ -1,86 +0,0 @@ -package v4 - -import ( - "context" - "crypto/sha256" - "encoding/hex" - "github.com/aws/aws-sdk-go-v2/aws" - v4Internal "github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4" - "strings" - "time" -) - -// EventStreamSigner is an AWS EventStream protocol signer. -type EventStreamSigner interface { - GetSignature(ctx context.Context, headers, payload []byte, signingTime time.Time, optFns ...func(*StreamSignerOptions)) ([]byte, error) -} - -// StreamSignerOptions is the configuration options for StreamSigner. -type StreamSignerOptions struct{} - -// StreamSigner implements Signature Version 4 (SigV4) signing of event stream encoded payloads. -type StreamSigner struct { - options StreamSignerOptions - - credentials aws.Credentials - service string - region string - - prevSignature []byte - - signingKeyDeriver *v4Internal.SigningKeyDeriver -} - -// NewStreamSigner returns a new AWS EventStream protocol signer. -func NewStreamSigner(credentials aws.Credentials, service, region string, seedSignature []byte, optFns ...func(*StreamSignerOptions)) *StreamSigner { - o := StreamSignerOptions{} - - for _, fn := range optFns { - fn(&o) - } - - return &StreamSigner{ - options: o, - credentials: credentials, - service: service, - region: region, - signingKeyDeriver: v4Internal.NewSigningKeyDeriver(), - prevSignature: seedSignature, - } -} - -// GetSignature signs the provided header and payload bytes. -func (s *StreamSigner) GetSignature(ctx context.Context, headers, payload []byte, signingTime time.Time, optFns ...func(*StreamSignerOptions)) ([]byte, error) { - options := s.options - - for _, fn := range optFns { - fn(&options) - } - - prevSignature := s.prevSignature - - st := v4Internal.NewSigningTime(signingTime.UTC()) - - sigKey := s.signingKeyDeriver.DeriveKey(s.credentials, s.service, s.region, st) - - scope := v4Internal.BuildCredentialScope(st, s.region, s.service) - - stringToSign := s.buildEventStreamStringToSign(headers, payload, prevSignature, scope, &st) - - signature := v4Internal.HMACSHA256(sigKey, []byte(stringToSign)) - s.prevSignature = signature - - return signature, nil -} - -func (s *StreamSigner) buildEventStreamStringToSign(headers, payload, previousSignature []byte, credentialScope string, signingTime *v4Internal.SigningTime) string { - hash := sha256.New() - return strings.Join([]string{ - "AWS4-HMAC-SHA256-PAYLOAD", - signingTime.TimeFormat(), - credentialScope, - hex.EncodeToString(previousSignature), - hex.EncodeToString(makeHash(hash, headers)), - hex.EncodeToString(makeHash(hash, payload)), - }, "\n") -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/v4.go deleted file mode 100644 index 7ed91d5..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/v4.go +++ /dev/null @@ -1,564 +0,0 @@ -// Package v4 implements the AWS signature version 4 algorithm (commonly known -// as SigV4). -// -// For more information about SigV4, see [Signing AWS API requests] in the IAM -// user guide. -// -// While this implementation CAN work in an external context, it is developed -// primarily for SDK use and you may encounter fringe behaviors around header -// canonicalization. -// -// # Pre-escaping a request URI -// -// AWS v4 signature validation requires that the canonical string's URI path -// component must be the escaped form of the HTTP request's path. -// -// The Go HTTP client will perform escaping automatically on the HTTP request. -// This may cause signature validation errors because the request differs from -// the URI path or query from which the signature was generated. -// -// Because of this, we recommend that you explicitly escape the request when -// using this signer outside of the SDK to prevent possible signature mismatch. -// This can be done by setting URL.Opaque on the request. The signer will -// prefer that value, falling back to the return of URL.EscapedPath if unset. -// -// When setting URL.Opaque you must do so in the form of: -// -// "///" -// -// // e.g. -// "//example.com/some/path" -// -// The leading "//" and hostname are required or the escaping will not work -// correctly. -// -// The TestStandaloneSign unit test provides a complete example of using the -// signer outside of the SDK and pre-escaping the URI path. -// -// [Signing AWS API requests]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html -package v4 - -import ( - "context" - "crypto/sha256" - "encoding/hex" - "fmt" - "hash" - "net/http" - "net/textproto" - "net/url" - "sort" - "strconv" - "strings" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - v4Internal "github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4" - "github.com/aws/smithy-go/encoding/httpbinding" - "github.com/aws/smithy-go/logging" -) - -const ( - signingAlgorithm = "AWS4-HMAC-SHA256" - authorizationHeader = "Authorization" - - // Version of signing v4 - Version = "SigV4" -) - -// HTTPSigner is an interface to a SigV4 signer that can sign HTTP requests -type HTTPSigner interface { - SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*SignerOptions)) error -} - -type keyDerivator interface { - DeriveKey(credential aws.Credentials, service, region string, signingTime v4Internal.SigningTime) []byte -} - -// SignerOptions is the SigV4 Signer options. -type SignerOptions struct { - // Disables the Signer's moving HTTP header key/value pairs from the HTTP - // request header to the request's query string. This is most commonly used - // with pre-signed requests preventing headers from being added to the - // request's query string. - DisableHeaderHoisting bool - - // Disables the automatic escaping of the URI path of the request for the - // siganture's canonical string's path. For services that do not need additional - // escaping then use this to disable the signer escaping the path. - // - // S3 is an example of a service that does not need additional escaping. - // - // http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html - DisableURIPathEscaping bool - - // The logger to send log messages to. - Logger logging.Logger - - // Enable logging of signed requests. - // This will enable logging of the canonical request, the string to sign, and for presigning the subsequent - // presigned URL. - LogSigning bool - - // Disables setting the session token on the request as part of signing - // through X-Amz-Security-Token. This is needed for variations of v4 that - // present the token elsewhere. - DisableSessionToken bool -} - -// Signer applies AWS v4 signing to given request. Use this to sign requests -// that need to be signed with AWS V4 Signatures. -type Signer struct { - options SignerOptions - keyDerivator keyDerivator -} - -// NewSigner returns a new SigV4 Signer -func NewSigner(optFns ...func(signer *SignerOptions)) *Signer { - options := SignerOptions{} - - for _, fn := range optFns { - fn(&options) - } - - return &Signer{options: options, keyDerivator: v4Internal.NewSigningKeyDeriver()} -} - -type httpSigner struct { - Request *http.Request - ServiceName string - Region string - Time v4Internal.SigningTime - Credentials aws.Credentials - KeyDerivator keyDerivator - IsPreSign bool - - PayloadHash string - - DisableHeaderHoisting bool - DisableURIPathEscaping bool - DisableSessionToken bool -} - -func (s *httpSigner) Build() (signedRequest, error) { - req := s.Request - - query := req.URL.Query() - headers := req.Header - - s.setRequiredSigningFields(headers, query) - - // Sort Each Query Key's Values - for key := range query { - sort.Strings(query[key]) - } - - v4Internal.SanitizeHostForHeader(req) - - credentialScope := s.buildCredentialScope() - credentialStr := s.Credentials.AccessKeyID + "/" + credentialScope - if s.IsPreSign { - query.Set(v4Internal.AmzCredentialKey, credentialStr) - } - - unsignedHeaders := headers - if s.IsPreSign && !s.DisableHeaderHoisting { - var urlValues url.Values - urlValues, unsignedHeaders = buildQuery(v4Internal.AllowedQueryHoisting, headers) - for k := range urlValues { - query[k] = urlValues[k] - } - } - - host := req.URL.Host - if len(req.Host) > 0 { - host = req.Host - } - - signedHeaders, signedHeadersStr, canonicalHeaderStr := s.buildCanonicalHeaders(host, v4Internal.IgnoredHeaders, unsignedHeaders, s.Request.ContentLength) - - if s.IsPreSign { - query.Set(v4Internal.AmzSignedHeadersKey, signedHeadersStr) - } - - var rawQuery strings.Builder - rawQuery.WriteString(strings.Replace(query.Encode(), "+", "%20", -1)) - - canonicalURI := v4Internal.GetURIPath(req.URL) - if !s.DisableURIPathEscaping { - canonicalURI = httpbinding.EscapePath(canonicalURI, false) - } - - canonicalString := s.buildCanonicalString( - req.Method, - canonicalURI, - rawQuery.String(), - signedHeadersStr, - canonicalHeaderStr, - ) - - strToSign := s.buildStringToSign(credentialScope, canonicalString) - signingSignature, err := s.buildSignature(strToSign) - if err != nil { - return signedRequest{}, err - } - - if s.IsPreSign { - rawQuery.WriteString("&X-Amz-Signature=") - rawQuery.WriteString(signingSignature) - } else { - headers[authorizationHeader] = append(headers[authorizationHeader][:0], buildAuthorizationHeader(credentialStr, signedHeadersStr, signingSignature)) - } - - req.URL.RawQuery = rawQuery.String() - - return signedRequest{ - Request: req, - SignedHeaders: signedHeaders, - CanonicalString: canonicalString, - StringToSign: strToSign, - PreSigned: s.IsPreSign, - }, nil -} - -func buildAuthorizationHeader(credentialStr, signedHeadersStr, signingSignature string) string { - const credential = "Credential=" - const signedHeaders = "SignedHeaders=" - const signature = "Signature=" - const commaSpace = ", " - - var parts strings.Builder - parts.Grow(len(signingAlgorithm) + 1 + - len(credential) + len(credentialStr) + 2 + - len(signedHeaders) + len(signedHeadersStr) + 2 + - len(signature) + len(signingSignature), - ) - parts.WriteString(signingAlgorithm) - parts.WriteRune(' ') - parts.WriteString(credential) - parts.WriteString(credentialStr) - parts.WriteString(commaSpace) - parts.WriteString(signedHeaders) - parts.WriteString(signedHeadersStr) - parts.WriteString(commaSpace) - parts.WriteString(signature) - parts.WriteString(signingSignature) - return parts.String() -} - -// SignHTTP signs AWS v4 requests with the provided payload hash, service name, region the -// request is made to, and time the request is signed at. The signTime allows -// you to specify that a request is signed for the future, and cannot be -// used until then. -// -// The payloadHash is the hex encoded SHA-256 hash of the request payload, and -// must be provided. Even if the request has no payload (aka body). If the -// request has no payload you should use the hex encoded SHA-256 of an empty -// string as the payloadHash value. -// -// "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" -// -// Some services such as Amazon S3 accept alternative values for the payload -// hash, such as "UNSIGNED-PAYLOAD" for requests where the body will not be -// included in the request signature. -// -// https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html -// -// Sign differs from Presign in that it will sign the request using HTTP -// header values. This type of signing is intended for http.Request values that -// will not be shared, or are shared in a way the header values on the request -// will not be lost. -// -// The passed in request will be modified in place. -func (s Signer) SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(options *SignerOptions)) error { - options := s.options - - for _, fn := range optFns { - fn(&options) - } - - signer := &httpSigner{ - Request: r, - PayloadHash: payloadHash, - ServiceName: service, - Region: region, - Credentials: credentials, - Time: v4Internal.NewSigningTime(signingTime.UTC()), - DisableHeaderHoisting: options.DisableHeaderHoisting, - DisableURIPathEscaping: options.DisableURIPathEscaping, - DisableSessionToken: options.DisableSessionToken, - KeyDerivator: s.keyDerivator, - } - - signedRequest, err := signer.Build() - if err != nil { - return err - } - - logSigningInfo(ctx, options, &signedRequest, false) - - return nil -} - -// PresignHTTP signs AWS v4 requests with the payload hash, service name, region -// the request is made to, and time the request is signed at. The signTime -// allows you to specify that a request is signed for the future, and cannot -// be used until then. -// -// Returns the signed URL and the map of HTTP headers that were included in the -// signature or an error if signing the request failed. For presigned requests -// these headers and their values must be included on the HTTP request when it -// is made. This is helpful to know what header values need to be shared with -// the party the presigned request will be distributed to. -// -// The payloadHash is the hex encoded SHA-256 hash of the request payload, and -// must be provided. Even if the request has no payload (aka body). If the -// request has no payload you should use the hex encoded SHA-256 of an empty -// string as the payloadHash value. -// -// "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" -// -// Some services such as Amazon S3 accept alternative values for the payload -// hash, such as "UNSIGNED-PAYLOAD" for requests where the body will not be -// included in the request signature. -// -// https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html -// -// PresignHTTP differs from SignHTTP in that it will sign the request using -// query string instead of header values. This allows you to share the -// Presigned Request's URL with third parties, or distribute it throughout your -// system with minimal dependencies. -// -// PresignHTTP will not set the expires time of the presigned request -// automatically. To specify the expire duration for a request add the -// "X-Amz-Expires" query parameter on the request with the value as the -// duration in seconds the presigned URL should be considered valid for. This -// parameter is not used by all AWS services, and is most notable used by -// Amazon S3 APIs. -// -// expires := 20 * time.Minute -// query := req.URL.Query() -// query.Set("X-Amz-Expires", strconv.FormatInt(int64(expires/time.Second), 10)) -// req.URL.RawQuery = query.Encode() -// -// This method does not modify the provided request. -func (s *Signer) PresignHTTP( - ctx context.Context, credentials aws.Credentials, r *http.Request, - payloadHash string, service string, region string, signingTime time.Time, - optFns ...func(*SignerOptions), -) (signedURI string, signedHeaders http.Header, err error) { - options := s.options - - for _, fn := range optFns { - fn(&options) - } - - signer := &httpSigner{ - Request: r.Clone(r.Context()), - PayloadHash: payloadHash, - ServiceName: service, - Region: region, - Credentials: credentials, - Time: v4Internal.NewSigningTime(signingTime.UTC()), - IsPreSign: true, - DisableHeaderHoisting: options.DisableHeaderHoisting, - DisableURIPathEscaping: options.DisableURIPathEscaping, - DisableSessionToken: options.DisableSessionToken, - KeyDerivator: s.keyDerivator, - } - - signedRequest, err := signer.Build() - if err != nil { - return "", nil, err - } - - logSigningInfo(ctx, options, &signedRequest, true) - - signedHeaders = make(http.Header) - - // For the signed headers we canonicalize the header keys in the returned map. - // This avoids situations where can standard library double headers like host header. For example the standard - // library will set the Host header, even if it is present in lower-case form. - for k, v := range signedRequest.SignedHeaders { - key := textproto.CanonicalMIMEHeaderKey(k) - signedHeaders[key] = append(signedHeaders[key], v...) - } - - return signedRequest.Request.URL.String(), signedHeaders, nil -} - -func (s *httpSigner) buildCredentialScope() string { - return v4Internal.BuildCredentialScope(s.Time, s.Region, s.ServiceName) -} - -func buildQuery(r v4Internal.Rule, header http.Header) (url.Values, http.Header) { - query := url.Values{} - unsignedHeaders := http.Header{} - - // A list of headers to be converted to lower case to mitigate a limitation from S3 - lowerCaseHeaders := map[string]string{ - "X-Amz-Expected-Bucket-Owner": "x-amz-expected-bucket-owner", // see #2508 - "X-Amz-Request-Payer": "x-amz-request-payer", // see #2764 - } - - for k, h := range header { - if newKey, ok := lowerCaseHeaders[k]; ok { - k = newKey - } - - if r.IsValid(k) { - query[k] = h - } else { - unsignedHeaders[k] = h - } - } - - return query, unsignedHeaders -} - -func (s *httpSigner) buildCanonicalHeaders(host string, rule v4Internal.Rule, header http.Header, length int64) (signed http.Header, signedHeaders, canonicalHeadersStr string) { - signed = make(http.Header) - - var headers []string - const hostHeader = "host" - headers = append(headers, hostHeader) - signed[hostHeader] = append(signed[hostHeader], host) - - const contentLengthHeader = "content-length" - if length > 0 { - headers = append(headers, contentLengthHeader) - signed[contentLengthHeader] = append(signed[contentLengthHeader], strconv.FormatInt(length, 10)) - } - - for k, v := range header { - if !rule.IsValid(k) { - continue // ignored header - } - if strings.EqualFold(k, contentLengthHeader) { - // prevent signing already handled content-length header. - continue - } - - lowerCaseKey := strings.ToLower(k) - if _, ok := signed[lowerCaseKey]; ok { - // include additional values - signed[lowerCaseKey] = append(signed[lowerCaseKey], v...) - continue - } - - headers = append(headers, lowerCaseKey) - signed[lowerCaseKey] = v - } - sort.Strings(headers) - - signedHeaders = strings.Join(headers, ";") - - var canonicalHeaders strings.Builder - n := len(headers) - const colon = ':' - for i := 0; i < n; i++ { - if headers[i] == hostHeader { - canonicalHeaders.WriteString(hostHeader) - canonicalHeaders.WriteRune(colon) - canonicalHeaders.WriteString(v4Internal.StripExcessSpaces(host)) - } else { - canonicalHeaders.WriteString(headers[i]) - canonicalHeaders.WriteRune(colon) - // Trim out leading, trailing, and dedup inner spaces from signed header values. - values := signed[headers[i]] - for j, v := range values { - cleanedValue := strings.TrimSpace(v4Internal.StripExcessSpaces(v)) - canonicalHeaders.WriteString(cleanedValue) - if j < len(values)-1 { - canonicalHeaders.WriteRune(',') - } - } - } - canonicalHeaders.WriteRune('\n') - } - canonicalHeadersStr = canonicalHeaders.String() - - return signed, signedHeaders, canonicalHeadersStr -} - -func (s *httpSigner) buildCanonicalString(method, uri, query, signedHeaders, canonicalHeaders string) string { - return strings.Join([]string{ - method, - uri, - query, - canonicalHeaders, - signedHeaders, - s.PayloadHash, - }, "\n") -} - -func (s *httpSigner) buildStringToSign(credentialScope, canonicalRequestString string) string { - return strings.Join([]string{ - signingAlgorithm, - s.Time.TimeFormat(), - credentialScope, - hex.EncodeToString(makeHash(sha256.New(), []byte(canonicalRequestString))), - }, "\n") -} - -func makeHash(hash hash.Hash, b []byte) []byte { - hash.Reset() - hash.Write(b) - return hash.Sum(nil) -} - -func (s *httpSigner) buildSignature(strToSign string) (string, error) { - key := s.KeyDerivator.DeriveKey(s.Credentials, s.ServiceName, s.Region, s.Time) - return hex.EncodeToString(v4Internal.HMACSHA256(key, []byte(strToSign))), nil -} - -func (s *httpSigner) setRequiredSigningFields(headers http.Header, query url.Values) { - amzDate := s.Time.TimeFormat() - - if s.IsPreSign { - query.Set(v4Internal.AmzAlgorithmKey, signingAlgorithm) - sessionToken := s.Credentials.SessionToken - if !s.DisableSessionToken && len(sessionToken) > 0 { - query.Set("X-Amz-Security-Token", sessionToken) - } - - query.Set(v4Internal.AmzDateKey, amzDate) - return - } - - headers[v4Internal.AmzDateKey] = append(headers[v4Internal.AmzDateKey][:0], amzDate) - - if !s.DisableSessionToken && len(s.Credentials.SessionToken) > 0 { - headers[v4Internal.AmzSecurityTokenKey] = append(headers[v4Internal.AmzSecurityTokenKey][:0], s.Credentials.SessionToken) - } -} - -func logSigningInfo(ctx context.Context, options SignerOptions, request *signedRequest, isPresign bool) { - if !options.LogSigning { - return - } - signedURLMsg := "" - if isPresign { - signedURLMsg = fmt.Sprintf(logSignedURLMsg, request.Request.URL.String()) - } - logger := logging.WithContext(ctx, options.Logger) - logger.Logf(logging.Debug, logSignInfoMsg, request.CanonicalString, request.StringToSign, signedURLMsg) -} - -type signedRequest struct { - Request *http.Request - SignedHeaders http.Header - CanonicalString string - StringToSign string - PreSigned bool -} - -const logSignInfoMsg = `Request Signature: ----[ CANONICAL STRING ]----------------------------- -%s ----[ STRING TO SIGN ]-------------------------------- -%s%s ------------------------------------------------------` -const logSignedURLMsg = ` ----[ SIGNED URL ]------------------------------------ -%s` diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/to_ptr.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/to_ptr.go deleted file mode 100644 index f3fc4d6..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/to_ptr.go +++ /dev/null @@ -1,297 +0,0 @@ -// Code generated by aws/generate.go DO NOT EDIT. - -package aws - -import ( - "github.com/aws/smithy-go/ptr" - "time" -) - -// Bool returns a pointer value for the bool value passed in. -func Bool(v bool) *bool { - return ptr.Bool(v) -} - -// BoolSlice returns a slice of bool pointers from the values -// passed in. -func BoolSlice(vs []bool) []*bool { - return ptr.BoolSlice(vs) -} - -// BoolMap returns a map of bool pointers from the values -// passed in. -func BoolMap(vs map[string]bool) map[string]*bool { - return ptr.BoolMap(vs) -} - -// Byte returns a pointer value for the byte value passed in. -func Byte(v byte) *byte { - return ptr.Byte(v) -} - -// ByteSlice returns a slice of byte pointers from the values -// passed in. -func ByteSlice(vs []byte) []*byte { - return ptr.ByteSlice(vs) -} - -// ByteMap returns a map of byte pointers from the values -// passed in. -func ByteMap(vs map[string]byte) map[string]*byte { - return ptr.ByteMap(vs) -} - -// String returns a pointer value for the string value passed in. -func String(v string) *string { - return ptr.String(v) -} - -// StringSlice returns a slice of string pointers from the values -// passed in. -func StringSlice(vs []string) []*string { - return ptr.StringSlice(vs) -} - -// StringMap returns a map of string pointers from the values -// passed in. -func StringMap(vs map[string]string) map[string]*string { - return ptr.StringMap(vs) -} - -// Int returns a pointer value for the int value passed in. -func Int(v int) *int { - return ptr.Int(v) -} - -// IntSlice returns a slice of int pointers from the values -// passed in. -func IntSlice(vs []int) []*int { - return ptr.IntSlice(vs) -} - -// IntMap returns a map of int pointers from the values -// passed in. -func IntMap(vs map[string]int) map[string]*int { - return ptr.IntMap(vs) -} - -// Int8 returns a pointer value for the int8 value passed in. -func Int8(v int8) *int8 { - return ptr.Int8(v) -} - -// Int8Slice returns a slice of int8 pointers from the values -// passed in. -func Int8Slice(vs []int8) []*int8 { - return ptr.Int8Slice(vs) -} - -// Int8Map returns a map of int8 pointers from the values -// passed in. -func Int8Map(vs map[string]int8) map[string]*int8 { - return ptr.Int8Map(vs) -} - -// Int16 returns a pointer value for the int16 value passed in. -func Int16(v int16) *int16 { - return ptr.Int16(v) -} - -// Int16Slice returns a slice of int16 pointers from the values -// passed in. -func Int16Slice(vs []int16) []*int16 { - return ptr.Int16Slice(vs) -} - -// Int16Map returns a map of int16 pointers from the values -// passed in. -func Int16Map(vs map[string]int16) map[string]*int16 { - return ptr.Int16Map(vs) -} - -// Int32 returns a pointer value for the int32 value passed in. -func Int32(v int32) *int32 { - return ptr.Int32(v) -} - -// Int32Slice returns a slice of int32 pointers from the values -// passed in. -func Int32Slice(vs []int32) []*int32 { - return ptr.Int32Slice(vs) -} - -// Int32Map returns a map of int32 pointers from the values -// passed in. -func Int32Map(vs map[string]int32) map[string]*int32 { - return ptr.Int32Map(vs) -} - -// Int64 returns a pointer value for the int64 value passed in. -func Int64(v int64) *int64 { - return ptr.Int64(v) -} - -// Int64Slice returns a slice of int64 pointers from the values -// passed in. -func Int64Slice(vs []int64) []*int64 { - return ptr.Int64Slice(vs) -} - -// Int64Map returns a map of int64 pointers from the values -// passed in. -func Int64Map(vs map[string]int64) map[string]*int64 { - return ptr.Int64Map(vs) -} - -// Uint returns a pointer value for the uint value passed in. -func Uint(v uint) *uint { - return ptr.Uint(v) -} - -// UintSlice returns a slice of uint pointers from the values -// passed in. -func UintSlice(vs []uint) []*uint { - return ptr.UintSlice(vs) -} - -// UintMap returns a map of uint pointers from the values -// passed in. -func UintMap(vs map[string]uint) map[string]*uint { - return ptr.UintMap(vs) -} - -// Uint8 returns a pointer value for the uint8 value passed in. -func Uint8(v uint8) *uint8 { - return ptr.Uint8(v) -} - -// Uint8Slice returns a slice of uint8 pointers from the values -// passed in. -func Uint8Slice(vs []uint8) []*uint8 { - return ptr.Uint8Slice(vs) -} - -// Uint8Map returns a map of uint8 pointers from the values -// passed in. -func Uint8Map(vs map[string]uint8) map[string]*uint8 { - return ptr.Uint8Map(vs) -} - -// Uint16 returns a pointer value for the uint16 value passed in. -func Uint16(v uint16) *uint16 { - return ptr.Uint16(v) -} - -// Uint16Slice returns a slice of uint16 pointers from the values -// passed in. -func Uint16Slice(vs []uint16) []*uint16 { - return ptr.Uint16Slice(vs) -} - -// Uint16Map returns a map of uint16 pointers from the values -// passed in. -func Uint16Map(vs map[string]uint16) map[string]*uint16 { - return ptr.Uint16Map(vs) -} - -// Uint32 returns a pointer value for the uint32 value passed in. -func Uint32(v uint32) *uint32 { - return ptr.Uint32(v) -} - -// Uint32Slice returns a slice of uint32 pointers from the values -// passed in. -func Uint32Slice(vs []uint32) []*uint32 { - return ptr.Uint32Slice(vs) -} - -// Uint32Map returns a map of uint32 pointers from the values -// passed in. -func Uint32Map(vs map[string]uint32) map[string]*uint32 { - return ptr.Uint32Map(vs) -} - -// Uint64 returns a pointer value for the uint64 value passed in. -func Uint64(v uint64) *uint64 { - return ptr.Uint64(v) -} - -// Uint64Slice returns a slice of uint64 pointers from the values -// passed in. -func Uint64Slice(vs []uint64) []*uint64 { - return ptr.Uint64Slice(vs) -} - -// Uint64Map returns a map of uint64 pointers from the values -// passed in. -func Uint64Map(vs map[string]uint64) map[string]*uint64 { - return ptr.Uint64Map(vs) -} - -// Float32 returns a pointer value for the float32 value passed in. -func Float32(v float32) *float32 { - return ptr.Float32(v) -} - -// Float32Slice returns a slice of float32 pointers from the values -// passed in. -func Float32Slice(vs []float32) []*float32 { - return ptr.Float32Slice(vs) -} - -// Float32Map returns a map of float32 pointers from the values -// passed in. -func Float32Map(vs map[string]float32) map[string]*float32 { - return ptr.Float32Map(vs) -} - -// Float64 returns a pointer value for the float64 value passed in. -func Float64(v float64) *float64 { - return ptr.Float64(v) -} - -// Float64Slice returns a slice of float64 pointers from the values -// passed in. -func Float64Slice(vs []float64) []*float64 { - return ptr.Float64Slice(vs) -} - -// Float64Map returns a map of float64 pointers from the values -// passed in. -func Float64Map(vs map[string]float64) map[string]*float64 { - return ptr.Float64Map(vs) -} - -// Time returns a pointer value for the time.Time value passed in. -func Time(v time.Time) *time.Time { - return ptr.Time(v) -} - -// TimeSlice returns a slice of time.Time pointers from the values -// passed in. -func TimeSlice(vs []time.Time) []*time.Time { - return ptr.TimeSlice(vs) -} - -// TimeMap returns a map of time.Time pointers from the values -// passed in. -func TimeMap(vs map[string]time.Time) map[string]*time.Time { - return ptr.TimeMap(vs) -} - -// Duration returns a pointer value for the time.Duration value passed in. -func Duration(v time.Duration) *time.Duration { - return ptr.Duration(v) -} - -// DurationSlice returns a slice of time.Duration pointers from the values -// passed in. -func DurationSlice(vs []time.Duration) []*time.Duration { - return ptr.DurationSlice(vs) -} - -// DurationMap returns a map of time.Duration pointers from the values -// passed in. -func DurationMap(vs map[string]time.Duration) map[string]*time.Duration { - return ptr.DurationMap(vs) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go deleted file mode 100644 index c7ef0ac..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go +++ /dev/null @@ -1,344 +0,0 @@ -package http - -import ( - "context" - "crypto/tls" - "net" - "net/http" - "reflect" - "sync" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/smithy-go/tracing" -) - -// Defaults for the HTTPTransportBuilder. -var ( - // Default connection pool options - DefaultHTTPTransportMaxIdleConns = 100 - DefaultHTTPTransportMaxIdleConnsPerHost = 10 - DefaultHTTPTransportMaxConnsPerHost = 2048 - - // Default connection timeouts - DefaultHTTPTransportIdleConnTimeout = 90 * time.Second - DefaultHTTPTransportTLSHandleshakeTimeout = 10 * time.Second - DefaultHTTPTransportExpectContinueTimeout = 1 * time.Second - - // Default to TLS 1.2 for all HTTPS requests. - DefaultHTTPTransportTLSMinVersion uint16 = tls.VersionTLS12 -) - -// Timeouts for net.Dialer's network connection. -var ( - DefaultDialConnectTimeout = 30 * time.Second - DefaultDialKeepAliveTimeout = 30 * time.Second -) - -// BuildableClient provides a HTTPClient implementation with options to -// create copies of the HTTPClient when additional configuration is provided. -// -// The client's methods will not share the http.Transport value between copies -// of the BuildableClient. Only exported member values of the Transport and -// optional Dialer will be copied between copies of BuildableClient. -type BuildableClient struct { - transport *http.Transport - dialer *net.Dialer - - initOnce sync.Once - - clientTimeout time.Duration - client *http.Client -} - -// NewBuildableClient returns an initialized client for invoking HTTP -// requests. -func NewBuildableClient() *BuildableClient { - return &BuildableClient{} -} - -// Do implements the HTTPClient interface's Do method to invoke a HTTP request, -// and receive the response. Uses the BuildableClient's current -// configuration to invoke the http.Request. -// -// If connection pooling is enabled (aka HTTP KeepAlive) the client will only -// share pooled connections with its own instance. Copies of the -// BuildableClient will have their own connection pools. -// -// Redirect (3xx) responses will not be followed, the HTTP response received -// will returned instead. -func (b *BuildableClient) Do(req *http.Request) (*http.Response, error) { - b.initOnce.Do(b.build) - - return b.client.Do(req) -} - -// Freeze returns a frozen aws.HTTPClient implementation that is no longer a BuildableClient. -// Use this to prevent the SDK from applying DefaultMode configuration values to a buildable client. -func (b *BuildableClient) Freeze() aws.HTTPClient { - cpy := b.clone() - cpy.build() - return cpy.client -} - -func (b *BuildableClient) build() { - b.client = wrapWithLimitedRedirect(&http.Client{ - Timeout: b.clientTimeout, - Transport: b.GetTransport(), - }) -} - -func (b *BuildableClient) clone() *BuildableClient { - cpy := NewBuildableClient() - cpy.transport = b.GetTransport() - cpy.dialer = b.GetDialer() - cpy.clientTimeout = b.clientTimeout - - return cpy -} - -// WithTransportOptions copies the BuildableClient and returns it with the -// http.Transport options applied. -// -// If a non (*http.Transport) was set as the round tripper, the round tripper -// will be replaced with a default Transport value before invoking the option -// functions. -func (b *BuildableClient) WithTransportOptions(opts ...func(*http.Transport)) *BuildableClient { - cpy := b.clone() - - tr := cpy.GetTransport() - for _, opt := range opts { - opt(tr) - } - cpy.transport = tr - - return cpy -} - -// WithDialerOptions copies the BuildableClient and returns it with the -// net.Dialer options applied. Will set the client's http.Transport DialContext -// member. -func (b *BuildableClient) WithDialerOptions(opts ...func(*net.Dialer)) *BuildableClient { - cpy := b.clone() - - dialer := cpy.GetDialer() - for _, opt := range opts { - opt(dialer) - } - cpy.dialer = dialer - - tr := cpy.GetTransport() - tr.DialContext = cpy.dialer.DialContext - cpy.transport = tr - - return cpy -} - -// WithTimeout Sets the timeout used by the client for all requests. -func (b *BuildableClient) WithTimeout(timeout time.Duration) *BuildableClient { - cpy := b.clone() - cpy.clientTimeout = timeout - return cpy -} - -// GetTransport returns a copy of the client's HTTP Transport. -func (b *BuildableClient) GetTransport() *http.Transport { - var tr *http.Transport - if b.transport != nil { - tr = b.transport.Clone() - } else { - tr = defaultHTTPTransport() - } - - return tr -} - -// GetDialer returns a copy of the client's network dialer. -func (b *BuildableClient) GetDialer() *net.Dialer { - var dialer *net.Dialer - if b.dialer != nil { - dialer = shallowCopyStruct(b.dialer).(*net.Dialer) - } else { - dialer = defaultDialer() - } - - return dialer -} - -// GetTimeout returns a copy of the client's timeout to cancel requests with. -func (b *BuildableClient) GetTimeout() time.Duration { - return b.clientTimeout -} - -func defaultDialer() *net.Dialer { - return &net.Dialer{ - Timeout: DefaultDialConnectTimeout, - KeepAlive: DefaultDialKeepAliveTimeout, - DualStack: true, - } -} - -func defaultHTTPTransport() *http.Transport { - dialer := defaultDialer() - - tr := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: traceDialContext(dialer.DialContext), - TLSHandshakeTimeout: DefaultHTTPTransportTLSHandleshakeTimeout, - MaxIdleConns: DefaultHTTPTransportMaxIdleConns, - MaxIdleConnsPerHost: DefaultHTTPTransportMaxIdleConnsPerHost, - MaxConnsPerHost: DefaultHTTPTransportMaxConnsPerHost, - IdleConnTimeout: DefaultHTTPTransportIdleConnTimeout, - ExpectContinueTimeout: DefaultHTTPTransportExpectContinueTimeout, - ForceAttemptHTTP2: true, - TLSClientConfig: &tls.Config{ - MinVersion: DefaultHTTPTransportTLSMinVersion, - }, - } - - return tr -} - -type dialContext func(ctx context.Context, network, addr string) (net.Conn, error) - -func traceDialContext(dc dialContext) dialContext { - return func(ctx context.Context, network, addr string) (net.Conn, error) { - span, _ := tracing.GetSpan(ctx) - span.SetProperty("net.peer.name", addr) - - conn, err := dc(ctx, network, addr) - if err != nil { - return conn, err - } - - raddr := conn.RemoteAddr() - if raddr == nil { - return conn, err - } - - host, port, err := net.SplitHostPort(raddr.String()) - if err != nil { // don't blow up just because we couldn't parse - span.SetProperty("net.peer.addr", raddr.String()) - } else { - span.SetProperty("net.peer.host", host) - span.SetProperty("net.peer.port", port) - } - - return conn, err - } -} - -// shallowCopyStruct creates a shallow copy of the passed in source struct, and -// returns that copy of the same struct type. -func shallowCopyStruct(src interface{}) interface{} { - srcVal := reflect.ValueOf(src) - srcValType := srcVal.Type() - - var returnAsPtr bool - if srcValType.Kind() == reflect.Ptr { - srcVal = srcVal.Elem() - srcValType = srcValType.Elem() - returnAsPtr = true - } - dstVal := reflect.New(srcValType).Elem() - - for i := 0; i < srcValType.NumField(); i++ { - ft := srcValType.Field(i) - if len(ft.PkgPath) != 0 { - // unexported fields have a PkgPath - continue - } - - dstVal.Field(i).Set(srcVal.Field(i)) - } - - if returnAsPtr { - dstVal = dstVal.Addr() - } - - return dstVal.Interface() -} - -// wrapWithLimitedRedirect updates the Client's Transport and CheckRedirect to -// not follow any redirect other than 307 and 308. No other redirect will be -// followed. -// -// If the client does not have a Transport defined will use a new SDK default -// http.Transport configuration. -func wrapWithLimitedRedirect(c *http.Client) *http.Client { - tr := c.Transport - if tr == nil { - tr = defaultHTTPTransport() - } - - cc := *c - cc.CheckRedirect = limitedRedirect - cc.Transport = suppressBadHTTPRedirectTransport{ - tr: tr, - } - - return &cc -} - -// limitedRedirect is a CheckRedirect that prevents the client from following -// any non 307/308 HTTP status code redirects. -// -// The 307 and 308 redirects are allowed because the client must use the -// original HTTP method for the redirected to location. Whereas 301 and 302 -// allow the client to switch to GET for the redirect. -// -// Suppresses all redirect requests with a URL of badHTTPRedirectLocation. -func limitedRedirect(r *http.Request, via []*http.Request) error { - // Request.Response, in CheckRedirect is the response that is triggering - // the redirect. - resp := r.Response - if r.URL.String() == badHTTPRedirectLocation { - resp.Header.Del(badHTTPRedirectLocation) - return http.ErrUseLastResponse - } - - switch resp.StatusCode { - case 307, 308: - // Only allow 307 and 308 redirects as they preserve the method. - return nil - } - - return http.ErrUseLastResponse -} - -// suppressBadHTTPRedirectTransport provides an http.RoundTripper -// implementation that wraps another http.RoundTripper to prevent HTTP client -// receiving 301 and 302 HTTP responses redirects without the required location -// header. -// -// Clients using this utility must have a CheckRedirect, e.g. limitedRedirect, -// that check for responses with having a URL of baseHTTPRedirectLocation, and -// suppress the redirect. -type suppressBadHTTPRedirectTransport struct { - tr http.RoundTripper -} - -const badHTTPRedirectLocation = `https://amazonaws.com/badhttpredirectlocation` - -// RoundTrip backfills a stub location when a 301/302 response is received -// without a location. This stub location is used by limitedRedirect to prevent -// the HTTP client from failing attempting to use follow a redirect without a -// location value. -func (t suppressBadHTTPRedirectTransport) RoundTrip(r *http.Request) (*http.Response, error) { - resp, err := t.tr.RoundTrip(r) - if err != nil { - return resp, err - } - - // S3 is the only known service to return 301 without location header. - // The Go standard library HTTP client will return an opaque error if it - // tries to follow a 301/302 response missing the location header. - switch resp.StatusCode { - case 301, 302: - if v := resp.Header.Get("Location"); len(v) == 0 { - resp.Header.Set("Location", badHTTPRedirectLocation) - } - } - - return resp, err -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/content_type.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/content_type.go deleted file mode 100644 index 556f54a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/content_type.go +++ /dev/null @@ -1,42 +0,0 @@ -package http - -import ( - "context" - "fmt" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// removeContentTypeHeader is a build middleware that removes -// content type header if content-length header is unset or -// is set to zero, -type removeContentTypeHeader struct { -} - -// ID the name of the middleware. -func (m *removeContentTypeHeader) ID() string { - return "RemoveContentTypeHeader" -} - -// HandleBuild adds or appends the constructed user agent to the request. -func (m *removeContentTypeHeader) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in) - } - - // remove contentTypeHeader when content-length is zero - if req.ContentLength == 0 { - req.Header.Del("content-type") - } - - return next.HandleBuild(ctx, in) -} - -// RemoveContentTypeHeader removes content-type header if -// content length is unset or equal to zero. -func RemoveContentTypeHeader(stack *middleware.Stack) error { - return stack.Build.Add(&removeContentTypeHeader{}, middleware.After) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/response_error.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/response_error.go deleted file mode 100644 index 44651c9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/response_error.go +++ /dev/null @@ -1,33 +0,0 @@ -package http - -import ( - "errors" - "fmt" - - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// ResponseError provides the HTTP centric error type wrapping the underlying error -// with the HTTP response value and the deserialized RequestID. -type ResponseError struct { - *smithyhttp.ResponseError - - // RequestID associated with response error - RequestID string -} - -// ServiceRequestID returns the request id associated with Response Error -func (e *ResponseError) ServiceRequestID() string { return e.RequestID } - -// Error returns the formatted error -func (e *ResponseError) Error() string { - return fmt.Sprintf( - "https response error StatusCode: %d, RequestID: %s, %v", - e.Response.StatusCode, e.RequestID, e.Err) -} - -// As populates target and returns true if the type of target is a error type that -// the ResponseError embeds, (e.g.AWS HTTP ResponseError) -func (e *ResponseError) As(target interface{}) bool { - return errors.As(e.ResponseError, target) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/response_error_middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/response_error_middleware.go deleted file mode 100644 index a1ad20f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/response_error_middleware.go +++ /dev/null @@ -1,56 +0,0 @@ -package http - -import ( - "context" - - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// AddResponseErrorMiddleware adds response error wrapper middleware -func AddResponseErrorMiddleware(stack *middleware.Stack) error { - // add error wrapper middleware before request id retriever middleware so that it can wrap the error response - // returned by operation deserializers - return stack.Deserialize.Insert(&ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before) -} - -// ResponseErrorWrapper wraps operation errors with ResponseError. -type ResponseErrorWrapper struct { -} - -// ID returns the middleware identifier -func (m *ResponseErrorWrapper) ID() string { - return "ResponseErrorWrapper" -} - -// HandleDeserialize wraps the stack error with smithyhttp.ResponseError. -func (m *ResponseErrorWrapper) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err == nil { - // Nothing to do when there is no error. - return out, metadata, err - } - - resp, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - // No raw response to wrap with. - return out, metadata, err - } - - // look for request id in metadata - reqID, _ := awsmiddleware.GetRequestIDMetadata(metadata) - - // Wrap the returned smithy error with the request id retrieved from the metadata - err = &ResponseError{ - ResponseError: &smithyhttp.ResponseError{ - Response: resp, - Err: err, - }, - RequestID: reqID, - } - - return out, metadata, err -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go deleted file mode 100644 index 4881ae1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go +++ /dev/null @@ -1,109 +0,0 @@ -package http - -import ( - "context" - "fmt" - "io" - "time" - - "github.com/aws/smithy-go" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -type readResult struct { - n int - err error -} - -// ResponseTimeoutError is an error when the reads from the response are -// delayed longer than the timeout the read was configured for. -type ResponseTimeoutError struct { - TimeoutDur time.Duration -} - -// Timeout returns that the error is was caused by a timeout, and can be -// retried. -func (*ResponseTimeoutError) Timeout() bool { return true } - -func (e *ResponseTimeoutError) Error() string { - return fmt.Sprintf("read on body reach timeout limit, %v", e.TimeoutDur) -} - -// timeoutReadCloser will handle body reads that take too long. -// We will return a ErrReadTimeout error if a timeout occurs. -type timeoutReadCloser struct { - reader io.ReadCloser - duration time.Duration -} - -// Read will spin off a goroutine to call the reader's Read method. We will -// select on the timer's channel or the read's channel. Whoever completes first -// will be returned. -func (r *timeoutReadCloser) Read(b []byte) (int, error) { - timer := time.NewTimer(r.duration) - c := make(chan readResult, 1) - - go func() { - n, err := r.reader.Read(b) - timer.Stop() - c <- readResult{n: n, err: err} - }() - - select { - case data := <-c: - return data.n, data.err - case <-timer.C: - return 0, &ResponseTimeoutError{TimeoutDur: r.duration} - } -} - -func (r *timeoutReadCloser) Close() error { - return r.reader.Close() -} - -// AddResponseReadTimeoutMiddleware adds a middleware to the stack that wraps the -// response body so that a read that takes too long will return an error. -// -// Deprecated: This API was previously exposed to customize behavior of the -// Kinesis service. That customization has been removed and this middleware's -// implementation can cause panics within the standard library networking loop. -// See #2752. -func AddResponseReadTimeoutMiddleware(stack *middleware.Stack, duration time.Duration) error { - return stack.Deserialize.Add(&readTimeout{duration: duration}, middleware.After) -} - -// readTimeout wraps the response body with a timeoutReadCloser -type readTimeout struct { - duration time.Duration -} - -// ID returns the id of the middleware -func (*readTimeout) ID() string { - return "ReadResponseTimeout" -} - -// HandleDeserialize implements the DeserializeMiddleware interface -func (m *readTimeout) HandleDeserialize( - ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - response.Body = &timeoutReadCloser{ - reader: response.Body, - duration: m.duration, - } - out.RawResponse = response - - return out, metadata, err -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/types.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/types.go deleted file mode 100644 index cc3ae81..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/types.go +++ /dev/null @@ -1,42 +0,0 @@ -package aws - -import ( - "fmt" -) - -// Ternary is an enum allowing an unknown or none state in addition to a bool's -// true and false. -type Ternary int - -func (t Ternary) String() string { - switch t { - case UnknownTernary: - return "unknown" - case FalseTernary: - return "false" - case TrueTernary: - return "true" - default: - return fmt.Sprintf("unknown value, %d", int(t)) - } -} - -// Bool returns true if the value is TrueTernary, false otherwise. -func (t Ternary) Bool() bool { - return t == TrueTernary -} - -// Enumerations for the values of the Ternary type. -const ( - UnknownTernary Ternary = iota - FalseTernary - TrueTernary -) - -// BoolTernary returns a true or false Ternary value for the bool provided. -func BoolTernary(v bool) Ternary { - if v { - return TrueTernary - } - return FalseTernary -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/version.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/version.go deleted file mode 100644 index 5f729d4..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/version.go +++ /dev/null @@ -1,8 +0,0 @@ -// Package aws provides core functionality for making requests to AWS services. -package aws - -// SDKName is the name of this AWS SDK -const SDKName = "aws-sdk-go-v2" - -// SDKVersion is the version of this SDK -const SDKVersion = goModuleVersion diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md deleted file mode 100644 index 9da5e6a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md +++ /dev/null @@ -1,820 +0,0 @@ -# v1.29.5 (2025-02-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.29.4 (2025-01-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.29.3 (2025-01-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.29.2 (2025-01-24) - -* **Bug Fix**: Fix env config naming and usage of deprecated ioutil -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v1.29.1 (2025-01-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.29.0 (2025-01-15) - -* **Feature**: S3 client behavior is updated to always calculate a checksum by default for operations that support it (such as PutObject or UploadPart), or require it (such as DeleteObjects). The checksum algorithm used by default now becomes CRC32. Checksum behavior can be configured using `when_supported` and `when_required` options - in code using RequestChecksumCalculation, in shared config using request_checksum_calculation, or as env variable using AWS_REQUEST_CHECKSUM_CALCULATION. The S3 client attempts to validate response checksums for all S3 API operations that support checksums. However, if the SDK has not implemented the specified checksum algorithm then this validation is skipped. Checksum validation behavior can be configured using `when_supported` and `when_required` options - in code using ResponseChecksumValidation, in shared config using response_checksum_validation, or as env variable using AWS_RESPONSE_CHECKSUM_VALIDATION. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.11 (2025-01-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.10 (2025-01-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.9 (2025-01-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.8 (2025-01-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.7 (2024-12-19) - -* **Bug Fix**: Fix improper use of printf-style functions. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.6 (2024-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.5 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.4 (2024-11-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.3 (2024-11-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.2 (2024-11-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.1 (2024-10-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.0 (2024-10-16) - -* **Feature**: Adds the LoadOptions hook `WithBaseEndpoint` for setting global endpoint override in-code. - -# v1.27.43 (2024-10-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.42 (2024-10-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.41 (2024-10-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.40 (2024-10-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.39 (2024-09-27) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.38 (2024-09-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.37 (2024-09-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.36 (2024-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.35 (2024-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.34 (2024-09-16) - -* **Bug Fix**: Read `AWS_CONTAINER_CREDENTIALS_FULL_URI` env variable if set when reading a profile with `credential_source`. Also ensure `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` is always read before it - -# v1.27.33 (2024-09-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.32 (2024-09-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.31 (2024-08-26) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.30 (2024-08-23) - -* **Bug Fix**: Don't fail credentials unit tests if credentials are found on a file - -# v1.27.29 (2024-08-22) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.28 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.27 (2024-07-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.26 (2024-07-10.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.25 (2024-07-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.24 (2024-07-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.23 (2024-06-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.22 (2024-06-26) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.21 (2024-06-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.20 (2024-06-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.19 (2024-06-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.18 (2024-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.17 (2024-06-03) - -* **Documentation**: Add deprecation docs to global endpoint resolution interfaces. These APIs were previously deprecated with the introduction of service-specific endpoint resolution (EndpointResolverV2 and BaseEndpoint on service client options). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.16 (2024-05-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.15 (2024-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.14 (2024-05-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.13 (2024-05-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.12 (2024-05-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.11 (2024-04-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.10 (2024-03-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.9 (2024-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.8 (2024-03-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.7 (2024-03-07) - -* **Bug Fix**: Remove dependency on go-cmp. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.6 (2024-03-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.5 (2024-03-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.4 (2024-02-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.3 (2024-02-22) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.2 (2024-02-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.1 (2024-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.6 (2024-01-22) - -* **Bug Fix**: Remove invalid escaping of shared config values. All values in the shared config file will now be interpreted literally, save for fully-quoted strings which are unwrapped for legacy reasons. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.5 (2024-01-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.4 (2024-01-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.3 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.2 (2023-12-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.1 (2023-12-08) - -* **Bug Fix**: Correct loading of [services *] sections into shared config. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.0 (2023-12-07) - -* **Feature**: Support modeled request compression. The only algorithm supported at this time is `gzip`. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.12 (2023-12-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.11 (2023-12-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.10 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.9 (2023-11-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.8 (2023-11-28.3) - -* **Bug Fix**: Correct resolution of S3Express auth disable toggle. - -# v1.25.7 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.6 (2023-11-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.5 (2023-11-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.4 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.3 (2023-11-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.2 (2023-11-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.1 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.0 (2023-11-14) - -* **Feature**: Add support for dynamic auth token from file and EKS container host in absolute/relative URIs in the HTTP credential provider. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.0 (2023-11-13) - -* **Feature**: Replace the legacy config parser with a modern, less-strict implementation. Parsing failures within a section will now simply ignore the invalid line rather than silently drop the entire section. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.0 (2023-11-09.2) - -* **Feature**: BREAKFIX: In order to support subproperty parsing, invalid property definitions must not be ignored -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.3 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.2 (2023-11-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.1 (2023-11-06) - -* No change notes available for this release. - -# v1.22.0 (2023-11-02) - -* **Feature**: Add env and shared config settings for disabling IMDSv1 fallback. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.0 (2023-11-01) - -* **Feature**: Adds support for configured endpoints via environment variables and the AWS shared configuration file. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.19.1 (2023-10-24) - -* No change notes available for this release. - -# v1.19.0 (2023-10-16) - -* **Feature**: Modify logic of retrieving user agent appID from env config - -# v1.18.45 (2023-10-12) - -* **Bug Fix**: Fail to load config if an explicitly provided profile doesn't exist. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.44 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.43 (2023-10-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.42 (2023-09-22) - -* **Bug Fix**: Fixed a bug where merging `max_attempts` or `duration_seconds` fields across shared config files with invalid values would silently default them to 0. -* **Bug Fix**: Move type assertion of config values out of the parsing stage, which resolves an issue where the contents of a profile would silently be dropped with certain numeric formats. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.41 (2023-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.40 (2023-09-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.39 (2023-09-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.38 (2023-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.37 (2023-08-23) - -* No change notes available for this release. - -# v1.18.36 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.35 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.34 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.33 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.32 (2023-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.31 (2023-07-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.30 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.29 (2023-07-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.28 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.27 (2023-06-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.26 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.25 (2023-05-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.24 (2023-05-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.23 (2023-05-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.22 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.21 (2023-04-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.20 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.19 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.18 (2023-03-16) - -* **Bug Fix**: Allow RoleARN to be set as functional option on STS WebIdentityRoleOptions. Fixes aws/aws-sdk-go-v2#2015. - -# v1.18.17 (2023-03-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.16 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.15 (2023-02-22) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.14 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.13 (2023-02-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.12 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.11 (2023-02-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.10 (2023-01-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.9 (2023-01-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.8 (2023-01-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.7 (2022-12-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.6 (2022-12-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.5 (2022-12-15) - -* **Bug Fix**: Unify logic between shared config and in finding home directory -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.4 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.3 (2022-11-22) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.2 (2022-11-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.1 (2022-11-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.0 (2022-11-11) - -* **Announcement**: When using the SSOTokenProvider, a previous implementation incorrectly compensated for invalid SSOTokenProvider configurations in the shared profile. This has been fixed via PR #1903 and tracked in issue #1846 -* **Feature**: Adds token refresh support (via SSOTokenProvider) when using the SSOCredentialProvider -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.11 (2022-11-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.10 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.9 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.8 (2022-09-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.7 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.6 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.5 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.4 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.3 (2022-08-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.2 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.1 (2022-08-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.0 (2022-08-14) - -* **Feature**: Add alternative mechanism for determning the users `$HOME` or `%USERPROFILE%` location when the environment variables are not present. - -# v1.16.1 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.0 (2022-08-10) - -* **Feature**: Adds support for the following settings in the `~/.aws/credentials` file: `sso_account_id`, `sso_region`, `sso_role_name`, `sso_start_url`, and `ca_bundle`. - -# v1.15.17 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.16 (2022-08-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.15 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.14 (2022-07-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.13 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.12 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.11 (2022-06-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.10 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.9 (2022-05-26) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.8 (2022-05-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.7 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.6 (2022-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.5 (2022-05-09) - -* **Bug Fix**: Fixes a bug in LoadDefaultConfig to correctly assign ConfigSources so all config resolvers have access to the config sources. This fixes the feature/ec2/imds client not having configuration applied via config.LoadOptions such as EC2IMDSClientEnableState. PR [#1682](https://github.com/aws/aws-sdk-go-v2/pull/1682) - -# v1.15.4 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.3 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.2 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.1 (2022-03-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.0 (2022-02-24) - -* **Feature**: Adds support for loading RetryMaxAttempts and RetryMod from the environment and shared configuration files. These parameters drive how the SDK's API client will initialize its default retryer, if custome retryer has not been specified. See [config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config) module and [aws.Config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Config) for more information about and how to use these new options. -* **Feature**: Adds support for the `ca_bundle` parameter in shared config and credentials files. The usage of the file is the same as environment variable, `AWS_CA_BUNDLE`, but sourced from shared config. Fixes [#1589](https://github.com/aws/aws-sdk-go-v2/issues/1589) -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.1 (2022-01-28) - -* **Bug Fix**: Fixes LoadDefaultConfig handling of errors returned by passed in functional options. Previously errors returned from the LoadOptions passed into LoadDefaultConfig were incorrectly ignored. [#1562](https://github.com/aws/aws-sdk-go-v2/pull/1562). Thanks to [Pinglei Guo](https://github.com/pingleig) for submitting this PR. -* **Bug Fix**: Fixes the SDK's handling of `duration_sections` in the shared credentials file or specified in multiple shared config and shared credentials files under the same profile. [#1568](https://github.com/aws/aws-sdk-go-v2/pull/1568). Thanks to [Amir Szekely](https://github.com/kichik) for help reproduce this bug. -* **Bug Fix**: Updates `config` module to use os.UserHomeDir instead of hard coded environment variable for OS. [#1563](https://github.com/aws/aws-sdk-go-v2/pull/1563) -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.0 (2022-01-14) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.0 (2022-01-07) - -* **Feature**: Add load option for CredentialCache. Adds a new member to the LoadOptions struct, CredentialsCacheOptions. This member allows specifying a function that will be used to configure the CredentialsCache. The CredentialsCacheOptions will only be used if the configuration loader will wrap the underlying credential provider in the CredentialsCache. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.1 (2021-12-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.0 (2021-12-02) - -* **Feature**: Add support for specifying `EndpointResolverWithOptions` on `LoadOptions`, and associated `WithEndpointResolverWithOptions`. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.3 (2021-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.2 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.1 (2021-11-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.0 (2021-11-06) - -* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.0 (2021-10-21) - -* **Feature**: Updated to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.3 (2021-10-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.2 (2021-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.1 (2021-09-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.0 (2021-09-02) - -* **Feature**: Add support for S3 Multi-Region Access Point ARNs. - -# v1.7.0 (2021-08-27) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.1 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.0 (2021-08-04) - -* **Feature**: adds error handling for defered close calls -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.0 (2021-07-15) - -* **Feature**: Support has been added for EC2 IPv6-enabled Instance Metadata Service Endpoints. -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.1 (2021-07-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.0 (2021-06-25) - -* **Feature**: Adds configuration setting for enabling endpoint discovery. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.0 (2021-05-20) - -* **Feature**: SSO credentials can now be defined alongside other credential providers within the same configuration profile. -* **Bug Fix**: Profile names were incorrectly normalized to lower-case, which could result in unexpected profile configurations. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.0 (2021-05-14) - -* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting. -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/config/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/config/config.go b/vendor/github.com/aws/aws-sdk-go-v2/config/config.go deleted file mode 100644 index 09d9b63..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/config.go +++ /dev/null @@ -1,228 +0,0 @@ -package config - -import ( - "context" - "os" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -// defaultAWSConfigResolvers are a slice of functions that will resolve external -// configuration values into AWS configuration values. -// -// This will setup the AWS configuration's Region, -var defaultAWSConfigResolvers = []awsConfigResolver{ - // Resolves the default configuration the SDK's aws.Config will be - // initialized with. - resolveDefaultAWSConfig, - - // Sets the logger to be used. Could be user provided logger, and client - // logging mode. - resolveLogger, - resolveClientLogMode, - - // Sets the HTTP client and configuration to use for making requests using - // the HTTP transport. - resolveHTTPClient, - resolveCustomCABundle, - - // Sets the endpoint resolving behavior the API Clients will use for making - // requests to. Clients default to their own clients this allows overrides - // to be specified. The resolveEndpointResolver option is deprecated, but - // we still need to set it for backwards compatibility on config - // construction. - resolveEndpointResolver, - resolveEndpointResolverWithOptions, - - // Sets the retry behavior API clients will use within their retry attempt - // middleware. Defaults to unset, allowing API clients to define their own - // retry behavior. - resolveRetryer, - - // Sets the region the API Clients should use for making requests to. - resolveRegion, - resolveEC2IMDSRegion, - resolveDefaultRegion, - - // Sets the additional set of middleware stack mutators that will custom - // API client request pipeline middleware. - resolveAPIOptions, - - // Resolves the DefaultsMode that should be used by SDK clients. If this - // mode is set to DefaultsModeAuto. - // - // Comes after HTTPClient and CustomCABundle to ensure the HTTP client is - // configured if provided before invoking IMDS if mode is auto. Comes - // before resolving credentials so that those subsequent clients use the - // configured auto mode. - resolveDefaultsModeOptions, - - // Sets the resolved credentials the API clients will use for - // authentication. Provides the SDK's default credential chain. - // - // Should probably be the last step in the resolve chain to ensure that all - // other configurations are resolved first in case downstream credentials - // implementations depend on or can be configured with earlier resolved - // configuration options. - resolveCredentials, - - // Sets the resolved bearer authentication token API clients will use for - // httpBearerAuth authentication scheme. - resolveBearerAuthToken, - - // Sets the sdk app ID if present in env var or shared config profile - resolveAppID, - - resolveBaseEndpoint, - - // Sets the DisableRequestCompression if present in env var or shared config profile - resolveDisableRequestCompression, - - // Sets the RequestMinCompressSizeBytes if present in env var or shared config profile - resolveRequestMinCompressSizeBytes, - - // Sets the AccountIDEndpointMode if present in env var or shared config profile - resolveAccountIDEndpointMode, - - // Sets the RequestChecksumCalculation if present in env var or shared config profile - resolveRequestChecksumCalculation, - - // Sets the ResponseChecksumValidation if present in env var or shared config profile - resolveResponseChecksumValidation, -} - -// A Config represents a generic configuration value or set of values. This type -// will be used by the AWSConfigResolvers to extract -// -// General the Config type will use type assertion against the Provider interfaces -// to extract specific data from the Config. -type Config interface{} - -// A loader is used to load external configuration data and returns it as -// a generic Config type. -// -// The loader should return an error if it fails to load the external configuration -// or the configuration data is malformed, or required components missing. -type loader func(context.Context, configs) (Config, error) - -// An awsConfigResolver will extract configuration data from the configs slice -// using the provider interfaces to extract specific functionality. The extracted -// configuration values will be written to the AWS Config value. -// -// The resolver should return an error if it it fails to extract the data, the -// data is malformed, or incomplete. -type awsConfigResolver func(ctx context.Context, cfg *aws.Config, configs configs) error - -// configs is a slice of Config values. These values will be used by the -// AWSConfigResolvers to extract external configuration values to populate the -// AWS Config type. -// -// Use AppendFromLoaders to add additional external Config values that are -// loaded from external sources. -// -// Use ResolveAWSConfig after external Config values have been added or loaded -// to extract the loaded configuration values into the AWS Config. -type configs []Config - -// AppendFromLoaders iterates over the slice of loaders passed in calling each -// loader function in order. The external config value returned by the loader -// will be added to the returned configs slice. -// -// If a loader returns an error this method will stop iterating and return -// that error. -func (cs configs) AppendFromLoaders(ctx context.Context, loaders []loader) (configs, error) { - for _, fn := range loaders { - cfg, err := fn(ctx, cs) - if err != nil { - return nil, err - } - - cs = append(cs, cfg) - } - - return cs, nil -} - -// ResolveAWSConfig returns a AWS configuration populated with values by calling -// the resolvers slice passed in. Each resolver is called in order. Any resolver -// may overwrite the AWS Configuration value of a previous resolver. -// -// If an resolver returns an error this method will return that error, and stop -// iterating over the resolvers. -func (cs configs) ResolveAWSConfig(ctx context.Context, resolvers []awsConfigResolver) (aws.Config, error) { - var cfg aws.Config - - for _, fn := range resolvers { - if err := fn(ctx, &cfg, cs); err != nil { - return aws.Config{}, err - } - } - - return cfg, nil -} - -// ResolveConfig calls the provide function passing slice of configuration sources. -// This implements the aws.ConfigResolver interface. -func (cs configs) ResolveConfig(f func(configs []interface{}) error) error { - var cfgs []interface{} - for i := range cs { - cfgs = append(cfgs, cs[i]) - } - return f(cfgs) -} - -// LoadDefaultConfig reads the SDK's default external configurations, and -// populates an AWS Config with the values from the external configurations. -// -// An optional variadic set of additional Config values can be provided as input -// that will be prepended to the configs slice. Use this to add custom configuration. -// The custom configurations must satisfy the respective providers for their data -// or the custom data will be ignored by the resolvers and config loaders. -// -// cfg, err := config.LoadDefaultConfig( context.TODO(), -// config.WithSharedConfigProfile("test-profile"), -// ) -// if err != nil { -// panic(fmt.Sprintf("failed loading config, %v", err)) -// } -// -// The default configuration sources are: -// * Environment Variables -// * Shared Configuration and Shared Credentials files. -func LoadDefaultConfig(ctx context.Context, optFns ...func(*LoadOptions) error) (cfg aws.Config, err error) { - var options LoadOptions - for _, optFn := range optFns { - if err := optFn(&options); err != nil { - return aws.Config{}, err - } - } - - // assign Load Options to configs - var cfgCpy = configs{options} - - cfgCpy, err = cfgCpy.AppendFromLoaders(ctx, resolveConfigLoaders(&options)) - if err != nil { - return aws.Config{}, err - } - - cfg, err = cfgCpy.ResolveAWSConfig(ctx, defaultAWSConfigResolvers) - if err != nil { - return aws.Config{}, err - } - - return cfg, nil -} - -func resolveConfigLoaders(options *LoadOptions) []loader { - loaders := make([]loader, 2) - loaders[0] = loadEnvConfig - - // specification of a profile should cause a load failure if it doesn't exist - if os.Getenv(awsProfileEnv) != "" || options.SharedConfigProfile != "" { - loaders[1] = loadSharedConfig - } else { - loaders[1] = loadSharedConfigIgnoreNotExist - } - - return loaders -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/defaultsmode.go b/vendor/github.com/aws/aws-sdk-go-v2/config/defaultsmode.go deleted file mode 100644 index 20b6636..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/defaultsmode.go +++ /dev/null @@ -1,47 +0,0 @@ -package config - -import ( - "context" - "os" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" -) - -const execEnvVar = "AWS_EXECUTION_ENV" - -// DefaultsModeOptions is the set of options that are used to configure -type DefaultsModeOptions struct { - // The SDK configuration defaults mode. Defaults to legacy if not specified. - // - // Supported modes are: auto, cross-region, in-region, legacy, mobile, standard - Mode aws.DefaultsMode - - // The EC2 Instance Metadata Client that should be used when performing environment - // discovery when aws.DefaultsModeAuto is set. - // - // If not specified the SDK will construct a client if the instance metadata service has not been disabled by - // the AWS_EC2_METADATA_DISABLED environment variable. - IMDSClient *imds.Client -} - -func resolveDefaultsModeRuntimeEnvironment(ctx context.Context, envConfig *EnvConfig, client *imds.Client) (aws.RuntimeEnvironment, error) { - getRegionOutput, err := client.GetRegion(ctx, &imds.GetRegionInput{}) - // honor context timeouts, but if we couldn't talk to IMDS don't fail runtime environment introspection. - select { - case <-ctx.Done(): - return aws.RuntimeEnvironment{}, err - default: - } - - var imdsRegion string - if err == nil { - imdsRegion = getRegionOutput.Region - } - - return aws.RuntimeEnvironment{ - EnvironmentIdentifier: aws.ExecutionEnvironmentID(os.Getenv(execEnvVar)), - Region: envConfig.Region, - EC2InstanceMetadataRegion: imdsRegion, - }, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/config/doc.go deleted file mode 100644 index aab7164..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -// Package config provides utilities for loading configuration from multiple -// sources that can be used to configure the SDK's API clients, and utilities. -// -// The config package will load configuration from environment variables, AWS -// shared configuration file (~/.aws/config), and AWS shared credentials file -// (~/.aws/credentials). -// -// Use the LoadDefaultConfig to load configuration from all the SDK's supported -// sources, and resolve credentials using the SDK's default credential chain. -// -// LoadDefaultConfig allows for a variadic list of additional Config sources that can -// provide one or more configuration values which can be used to programmatically control the resolution -// of a specific value, or allow for broader range of additional configuration sources not supported by the SDK. -// A Config source implements one or more provider interfaces defined in this package. Config sources passed in will -// take precedence over the default environment and shared config sources used by the SDK. If one or more Config sources -// implement the same provider interface, priority will be handled by the order in which the sources were passed in. -// -// A number of helpers (prefixed by “With“) are provided in this package that implement their respective provider -// interface. These helpers should be used for overriding configuration programmatically at runtime. -package config diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go b/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go deleted file mode 100644 index 9db507e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go +++ /dev/null @@ -1,918 +0,0 @@ -package config - -import ( - "bytes" - "context" - "fmt" - "io" - "os" - "strconv" - "strings" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - smithyrequestcompression "github.com/aws/smithy-go/private/requestcompression" -) - -// CredentialsSourceName provides a name of the provider when config is -// loaded from environment. -const CredentialsSourceName = "EnvConfigCredentials" - -// Environment variables that will be read for configuration values. -const ( - awsAccessKeyIDEnv = "AWS_ACCESS_KEY_ID" - awsAccessKeyEnv = "AWS_ACCESS_KEY" - - awsSecretAccessKeyEnv = "AWS_SECRET_ACCESS_KEY" - awsSecretKeyEnv = "AWS_SECRET_KEY" - - awsSessionTokenEnv = "AWS_SESSION_TOKEN" - - awsContainerCredentialsFullURIEnv = "AWS_CONTAINER_CREDENTIALS_FULL_URI" - awsContainerCredentialsRelativeURIEnv = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" - awsContainerAuthorizationTokenEnv = "AWS_CONTAINER_AUTHORIZATION_TOKEN" - - awsRegionEnv = "AWS_REGION" - awsDefaultRegionEnv = "AWS_DEFAULT_REGION" - - awsProfileEnv = "AWS_PROFILE" - awsDefaultProfileEnv = "AWS_DEFAULT_PROFILE" - - awsSharedCredentialsFileEnv = "AWS_SHARED_CREDENTIALS_FILE" - - awsConfigFileEnv = "AWS_CONFIG_FILE" - - awsCABundleEnv = "AWS_CA_BUNDLE" - - awsWebIdentityTokenFileEnv = "AWS_WEB_IDENTITY_TOKEN_FILE" - - awsRoleARNEnv = "AWS_ROLE_ARN" - awsRoleSessionNameEnv = "AWS_ROLE_SESSION_NAME" - - awsEnableEndpointDiscoveryEnv = "AWS_ENABLE_ENDPOINT_DISCOVERY" - - awsS3UseARNRegionEnv = "AWS_S3_USE_ARN_REGION" - - awsEc2MetadataServiceEndpointModeEnv = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE" - - awsEc2MetadataServiceEndpointEnv = "AWS_EC2_METADATA_SERVICE_ENDPOINT" - - awsEc2MetadataDisabledEnv = "AWS_EC2_METADATA_DISABLED" - awsEc2MetadataV1DisabledEnv = "AWS_EC2_METADATA_V1_DISABLED" - - awsS3DisableMultiRegionAccessPointsEnv = "AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS" - - awsUseDualStackEndpointEnv = "AWS_USE_DUALSTACK_ENDPOINT" - - awsUseFIPSEndpointEnv = "AWS_USE_FIPS_ENDPOINT" - - awsDefaultsModeEnv = "AWS_DEFAULTS_MODE" - - awsMaxAttemptsEnv = "AWS_MAX_ATTEMPTS" - awsRetryModeEnv = "AWS_RETRY_MODE" - awsSdkUaAppIDEnv = "AWS_SDK_UA_APP_ID" - - awsIgnoreConfiguredEndpointURLEnv = "AWS_IGNORE_CONFIGURED_ENDPOINT_URLS" - awsEndpointURLEnv = "AWS_ENDPOINT_URL" - - awsDisableRequestCompressionEnv = "AWS_DISABLE_REQUEST_COMPRESSION" - awsRequestMinCompressionSizeBytesEnv = "AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES" - - awsS3DisableExpressSessionAuthEnv = "AWS_S3_DISABLE_EXPRESS_SESSION_AUTH" - - awsAccountIDEnv = "AWS_ACCOUNT_ID" - awsAccountIDEndpointModeEnv = "AWS_ACCOUNT_ID_ENDPOINT_MODE" - - awsRequestChecksumCalculation = "AWS_REQUEST_CHECKSUM_CALCULATION" - awsResponseChecksumValidation = "AWS_RESPONSE_CHECKSUM_VALIDATION" -) - -var ( - credAccessEnvKeys = []string{ - awsAccessKeyIDEnv, - awsAccessKeyEnv, - } - credSecretEnvKeys = []string{ - awsSecretAccessKeyEnv, - awsSecretKeyEnv, - } - regionEnvKeys = []string{ - awsRegionEnv, - awsDefaultRegionEnv, - } - profileEnvKeys = []string{ - awsProfileEnv, - awsDefaultProfileEnv, - } -) - -// EnvConfig is a collection of environment values the SDK will read -// setup config from. All environment values are optional. But some values -// such as credentials require multiple values to be complete or the values -// will be ignored. -type EnvConfig struct { - // Environment configuration values. If set both Access Key ID and Secret Access - // Key must be provided. Session Token and optionally also be provided, but is - // not required. - // - // # Access Key ID - // AWS_ACCESS_KEY_ID=AKID - // AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. - // - // # Secret Access Key - // AWS_SECRET_ACCESS_KEY=SECRET - // AWS_SECRET_KEY=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. - // - // # Session Token - // AWS_SESSION_TOKEN=TOKEN - Credentials aws.Credentials - - // ContainerCredentialsEndpoint value is the HTTP enabled endpoint to retrieve credentials - // using the endpointcreds.Provider - ContainerCredentialsEndpoint string - - // ContainerCredentialsRelativePath is the relative URI path that will be used when attempting to retrieve - // credentials from the container endpoint. - ContainerCredentialsRelativePath string - - // ContainerAuthorizationToken is the authorization token that will be included in the HTTP Authorization - // header when attempting to retrieve credentials from the container credentials endpoint. - ContainerAuthorizationToken string - - // Region value will instruct the SDK where to make service API requests to. If is - // not provided in the environment the region must be provided before a service - // client request is made. - // - // AWS_REGION=us-west-2 - // AWS_DEFAULT_REGION=us-west-2 - Region string - - // Profile name the SDK should load use when loading shared configuration from the - // shared configuration files. If not provided "default" will be used as the - // profile name. - // - // AWS_PROFILE=my_profile - // AWS_DEFAULT_PROFILE=my_profile - SharedConfigProfile string - - // Shared credentials file path can be set to instruct the SDK to use an alternate - // file for the shared credentials. If not set the file will be loaded from - // $HOME/.aws/credentials on Linux/Unix based systems, and - // %USERPROFILE%\.aws\credentials on Windows. - // - // AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials - SharedCredentialsFile string - - // Shared config file path can be set to instruct the SDK to use an alternate - // file for the shared config. If not set the file will be loaded from - // $HOME/.aws/config on Linux/Unix based systems, and - // %USERPROFILE%\.aws\config on Windows. - // - // AWS_CONFIG_FILE=$HOME/my_shared_config - SharedConfigFile string - - // Sets the path to a custom Credentials Authority (CA) Bundle PEM file - // that the SDK will use instead of the system's root CA bundle. - // Only use this if you want to configure the SDK to use a custom set - // of CAs. - // - // Enabling this option will attempt to merge the Transport - // into the SDK's HTTP client. If the client's Transport is - // not a http.Transport an error will be returned. If the - // Transport's TLS config is set this option will cause the - // SDK to overwrite the Transport's TLS config's RootCAs value. - // - // Setting a custom HTTPClient in the aws.Config options will override this setting. - // To use this option and custom HTTP client, the HTTP client needs to be provided - // when creating the config. Not the service client. - // - // AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle - CustomCABundle string - - // Enables endpoint discovery via environment variables. - // - // AWS_ENABLE_ENDPOINT_DISCOVERY=true - EnableEndpointDiscovery aws.EndpointDiscoveryEnableState - - // Specifies the WebIdentity token the SDK should use to assume a role - // with. - // - // AWS_WEB_IDENTITY_TOKEN_FILE=file_path - WebIdentityTokenFilePath string - - // Specifies the IAM role arn to use when assuming an role. - // - // AWS_ROLE_ARN=role_arn - RoleARN string - - // Specifies the IAM role session name to use when assuming a role. - // - // AWS_ROLE_SESSION_NAME=session_name - RoleSessionName string - - // Specifies if the S3 service should allow ARNs to direct the region - // the client's requests are sent to. - // - // AWS_S3_USE_ARN_REGION=true - S3UseARNRegion *bool - - // Specifies if the EC2 IMDS service client is enabled. - // - // AWS_EC2_METADATA_DISABLED=true - EC2IMDSClientEnableState imds.ClientEnableState - - // Specifies if EC2 IMDSv1 fallback is disabled. - // - // AWS_EC2_METADATA_V1_DISABLED=true - EC2IMDSv1Disabled *bool - - // Specifies the EC2 Instance Metadata Service default endpoint selection mode (IPv4 or IPv6) - // - // AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE=IPv6 - EC2IMDSEndpointMode imds.EndpointModeState - - // Specifies the EC2 Instance Metadata Service endpoint to use. If specified it overrides EC2IMDSEndpointMode. - // - // AWS_EC2_METADATA_SERVICE_ENDPOINT=http://fd00:ec2::254 - EC2IMDSEndpoint string - - // Specifies if the S3 service should disable multi-region access points - // support. - // - // AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS=true - S3DisableMultiRegionAccessPoints *bool - - // Specifies that SDK clients must resolve a dual-stack endpoint for - // services. - // - // AWS_USE_DUALSTACK_ENDPOINT=true - UseDualStackEndpoint aws.DualStackEndpointState - - // Specifies that SDK clients must resolve a FIPS endpoint for - // services. - // - // AWS_USE_FIPS_ENDPOINT=true - UseFIPSEndpoint aws.FIPSEndpointState - - // Specifies the SDK Defaults Mode used by services. - // - // AWS_DEFAULTS_MODE=standard - DefaultsMode aws.DefaultsMode - - // Specifies the maximum number attempts an API client will call an - // operation that fails with a retryable error. - // - // AWS_MAX_ATTEMPTS=3 - RetryMaxAttempts int - - // Specifies the retry model the API client will be created with. - // - // aws_retry_mode=standard - RetryMode aws.RetryMode - - // aws sdk app ID that can be added to user agent header string - AppID string - - // Flag used to disable configured endpoints. - IgnoreConfiguredEndpoints *bool - - // Value to contain configured endpoints to be propagated to - // corresponding endpoint resolution field. - BaseEndpoint string - - // determine if request compression is allowed, default to false - // retrieved from env var AWS_DISABLE_REQUEST_COMPRESSION - DisableRequestCompression *bool - - // inclusive threshold request body size to trigger compression, - // default to 10240 and must be within 0 and 10485760 bytes inclusive - // retrieved from env var AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES - RequestMinCompressSizeBytes *int64 - - // Whether S3Express auth is disabled. - // - // This will NOT prevent requests from being made to S3Express buckets, it - // will only bypass the modified endpoint routing and signing behaviors - // associated with the feature. - S3DisableExpressAuth *bool - - // Indicates whether account ID will be required/ignored in endpoint2.0 routing - AccountIDEndpointMode aws.AccountIDEndpointMode - - // Indicates whether request checksum should be calculated - RequestChecksumCalculation aws.RequestChecksumCalculation - - // Indicates whether response checksum should be validated - ResponseChecksumValidation aws.ResponseChecksumValidation -} - -// loadEnvConfig reads configuration values from the OS's environment variables. -// Returning the a Config typed EnvConfig to satisfy the ConfigLoader func type. -func loadEnvConfig(ctx context.Context, cfgs configs) (Config, error) { - return NewEnvConfig() -} - -// NewEnvConfig retrieves the SDK's environment configuration. -// See `EnvConfig` for the values that will be retrieved. -func NewEnvConfig() (EnvConfig, error) { - var cfg EnvConfig - - creds := aws.Credentials{ - Source: CredentialsSourceName, - } - setStringFromEnvVal(&creds.AccessKeyID, credAccessEnvKeys) - setStringFromEnvVal(&creds.SecretAccessKey, credSecretEnvKeys) - if creds.HasKeys() { - creds.AccountID = os.Getenv(awsAccountIDEnv) - creds.SessionToken = os.Getenv(awsSessionTokenEnv) - cfg.Credentials = creds - } - - cfg.ContainerCredentialsEndpoint = os.Getenv(awsContainerCredentialsFullURIEnv) - cfg.ContainerCredentialsRelativePath = os.Getenv(awsContainerCredentialsRelativeURIEnv) - cfg.ContainerAuthorizationToken = os.Getenv(awsContainerAuthorizationTokenEnv) - - setStringFromEnvVal(&cfg.Region, regionEnvKeys) - setStringFromEnvVal(&cfg.SharedConfigProfile, profileEnvKeys) - - cfg.SharedCredentialsFile = os.Getenv(awsSharedCredentialsFileEnv) - cfg.SharedConfigFile = os.Getenv(awsConfigFileEnv) - - cfg.CustomCABundle = os.Getenv(awsCABundleEnv) - - cfg.WebIdentityTokenFilePath = os.Getenv(awsWebIdentityTokenFileEnv) - - cfg.RoleARN = os.Getenv(awsRoleARNEnv) - cfg.RoleSessionName = os.Getenv(awsRoleSessionNameEnv) - - cfg.AppID = os.Getenv(awsSdkUaAppIDEnv) - - if err := setBoolPtrFromEnvVal(&cfg.DisableRequestCompression, []string{awsDisableRequestCompressionEnv}); err != nil { - return cfg, err - } - if err := setInt64PtrFromEnvVal(&cfg.RequestMinCompressSizeBytes, []string{awsRequestMinCompressionSizeBytesEnv}, smithyrequestcompression.MaxRequestMinCompressSizeBytes); err != nil { - return cfg, err - } - - if err := setEndpointDiscoveryTypeFromEnvVal(&cfg.EnableEndpointDiscovery, []string{awsEnableEndpointDiscoveryEnv}); err != nil { - return cfg, err - } - - if err := setBoolPtrFromEnvVal(&cfg.S3UseARNRegion, []string{awsS3UseARNRegionEnv}); err != nil { - return cfg, err - } - - setEC2IMDSClientEnableState(&cfg.EC2IMDSClientEnableState, []string{awsEc2MetadataDisabledEnv}) - if err := setEC2IMDSEndpointMode(&cfg.EC2IMDSEndpointMode, []string{awsEc2MetadataServiceEndpointModeEnv}); err != nil { - return cfg, err - } - cfg.EC2IMDSEndpoint = os.Getenv(awsEc2MetadataServiceEndpointEnv) - if err := setBoolPtrFromEnvVal(&cfg.EC2IMDSv1Disabled, []string{awsEc2MetadataV1DisabledEnv}); err != nil { - return cfg, err - } - - if err := setBoolPtrFromEnvVal(&cfg.S3DisableMultiRegionAccessPoints, []string{awsS3DisableMultiRegionAccessPointsEnv}); err != nil { - return cfg, err - } - - if err := setUseDualStackEndpointFromEnvVal(&cfg.UseDualStackEndpoint, []string{awsUseDualStackEndpointEnv}); err != nil { - return cfg, err - } - - if err := setUseFIPSEndpointFromEnvVal(&cfg.UseFIPSEndpoint, []string{awsUseFIPSEndpointEnv}); err != nil { - return cfg, err - } - - if err := setDefaultsModeFromEnvVal(&cfg.DefaultsMode, []string{awsDefaultsModeEnv}); err != nil { - return cfg, err - } - - if err := setIntFromEnvVal(&cfg.RetryMaxAttempts, []string{awsMaxAttemptsEnv}); err != nil { - return cfg, err - } - if err := setRetryModeFromEnvVal(&cfg.RetryMode, []string{awsRetryModeEnv}); err != nil { - return cfg, err - } - - setStringFromEnvVal(&cfg.BaseEndpoint, []string{awsEndpointURLEnv}) - - if err := setBoolPtrFromEnvVal(&cfg.IgnoreConfiguredEndpoints, []string{awsIgnoreConfiguredEndpointURLEnv}); err != nil { - return cfg, err - } - - if err := setBoolPtrFromEnvVal(&cfg.S3DisableExpressAuth, []string{awsS3DisableExpressSessionAuthEnv}); err != nil { - return cfg, err - } - - if err := setAIDEndPointModeFromEnvVal(&cfg.AccountIDEndpointMode, []string{awsAccountIDEndpointModeEnv}); err != nil { - return cfg, err - } - - if err := setRequestChecksumCalculationFromEnvVal(&cfg.RequestChecksumCalculation, []string{awsRequestChecksumCalculation}); err != nil { - return cfg, err - } - if err := setResponseChecksumValidationFromEnvVal(&cfg.ResponseChecksumValidation, []string{awsResponseChecksumValidation}); err != nil { - return cfg, err - } - - return cfg, nil -} - -func (c EnvConfig) getDefaultsMode(ctx context.Context) (aws.DefaultsMode, bool, error) { - if len(c.DefaultsMode) == 0 { - return "", false, nil - } - return c.DefaultsMode, true, nil -} - -func (c EnvConfig) getAppID(context.Context) (string, bool, error) { - return c.AppID, len(c.AppID) > 0, nil -} - -func (c EnvConfig) getDisableRequestCompression(context.Context) (bool, bool, error) { - if c.DisableRequestCompression == nil { - return false, false, nil - } - return *c.DisableRequestCompression, true, nil -} - -func (c EnvConfig) getRequestMinCompressSizeBytes(context.Context) (int64, bool, error) { - if c.RequestMinCompressSizeBytes == nil { - return 0, false, nil - } - return *c.RequestMinCompressSizeBytes, true, nil -} - -func (c EnvConfig) getAccountIDEndpointMode(context.Context) (aws.AccountIDEndpointMode, bool, error) { - return c.AccountIDEndpointMode, len(c.AccountIDEndpointMode) > 0, nil -} - -func (c EnvConfig) getRequestChecksumCalculation(context.Context) (aws.RequestChecksumCalculation, bool, error) { - return c.RequestChecksumCalculation, c.RequestChecksumCalculation > 0, nil -} - -func (c EnvConfig) getResponseChecksumValidation(context.Context) (aws.ResponseChecksumValidation, bool, error) { - return c.ResponseChecksumValidation, c.ResponseChecksumValidation > 0, nil -} - -// GetRetryMaxAttempts returns the value of AWS_MAX_ATTEMPTS if was specified, -// and not 0. -func (c EnvConfig) GetRetryMaxAttempts(ctx context.Context) (int, bool, error) { - if c.RetryMaxAttempts == 0 { - return 0, false, nil - } - return c.RetryMaxAttempts, true, nil -} - -// GetRetryMode returns the RetryMode of AWS_RETRY_MODE if was specified, and a -// valid value. -func (c EnvConfig) GetRetryMode(ctx context.Context) (aws.RetryMode, bool, error) { - if len(c.RetryMode) == 0 { - return "", false, nil - } - return c.RetryMode, true, nil -} - -func setEC2IMDSClientEnableState(state *imds.ClientEnableState, keys []string) { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue - } - switch { - case strings.EqualFold(value, "true"): - *state = imds.ClientDisabled - case strings.EqualFold(value, "false"): - *state = imds.ClientEnabled - default: - continue - } - break - } -} - -func setDefaultsModeFromEnvVal(mode *aws.DefaultsMode, keys []string) error { - for _, k := range keys { - if value := os.Getenv(k); len(value) > 0 { - if ok := mode.SetFromString(value); !ok { - return fmt.Errorf("invalid %s value: %s", k, value) - } - break - } - } - return nil -} - -func setRetryModeFromEnvVal(mode *aws.RetryMode, keys []string) (err error) { - for _, k := range keys { - if value := os.Getenv(k); len(value) > 0 { - *mode, err = aws.ParseRetryMode(value) - if err != nil { - return fmt.Errorf("invalid %s value, %w", k, err) - } - break - } - } - return nil -} - -func setEC2IMDSEndpointMode(mode *imds.EndpointModeState, keys []string) error { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue - } - if err := mode.SetFromString(value); err != nil { - return fmt.Errorf("invalid value for environment variable, %s=%s, %v", k, value, err) - } - } - return nil -} - -func setAIDEndPointModeFromEnvVal(m *aws.AccountIDEndpointMode, keys []string) error { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue - } - - switch value { - case "preferred": - *m = aws.AccountIDEndpointModePreferred - case "required": - *m = aws.AccountIDEndpointModeRequired - case "disabled": - *m = aws.AccountIDEndpointModeDisabled - default: - return fmt.Errorf("invalid value for environment variable, %s=%s, must be preferred/required/disabled", k, value) - } - break - } - return nil -} - -func setRequestChecksumCalculationFromEnvVal(m *aws.RequestChecksumCalculation, keys []string) error { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue - } - - switch strings.ToLower(value) { - case checksumWhenSupported: - *m = aws.RequestChecksumCalculationWhenSupported - case checksumWhenRequired: - *m = aws.RequestChecksumCalculationWhenRequired - default: - return fmt.Errorf("invalid value for environment variable, %s=%s, must be when_supported/when_required", k, value) - } - } - return nil -} - -func setResponseChecksumValidationFromEnvVal(m *aws.ResponseChecksumValidation, keys []string) error { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue - } - - switch strings.ToLower(value) { - case checksumWhenSupported: - *m = aws.ResponseChecksumValidationWhenSupported - case checksumWhenRequired: - *m = aws.ResponseChecksumValidationWhenRequired - default: - return fmt.Errorf("invalid value for environment variable, %s=%s, must be when_supported/when_required", k, value) - } - - } - return nil -} - -// GetRegion returns the AWS Region if set in the environment. Returns an empty -// string if not set. -func (c EnvConfig) getRegion(ctx context.Context) (string, bool, error) { - if len(c.Region) == 0 { - return "", false, nil - } - return c.Region, true, nil -} - -// GetSharedConfigProfile returns the shared config profile if set in the -// environment. Returns an empty string if not set. -func (c EnvConfig) getSharedConfigProfile(ctx context.Context) (string, bool, error) { - if len(c.SharedConfigProfile) == 0 { - return "", false, nil - } - - return c.SharedConfigProfile, true, nil -} - -// getSharedConfigFiles returns a slice of filenames set in the environment. -// -// Will return the filenames in the order of: -// * Shared Config -func (c EnvConfig) getSharedConfigFiles(context.Context) ([]string, bool, error) { - var files []string - if v := c.SharedConfigFile; len(v) > 0 { - files = append(files, v) - } - - if len(files) == 0 { - return nil, false, nil - } - return files, true, nil -} - -// getSharedCredentialsFiles returns a slice of filenames set in the environment. -// -// Will return the filenames in the order of: -// * Shared Credentials -func (c EnvConfig) getSharedCredentialsFiles(context.Context) ([]string, bool, error) { - var files []string - if v := c.SharedCredentialsFile; len(v) > 0 { - files = append(files, v) - } - if len(files) == 0 { - return nil, false, nil - } - return files, true, nil -} - -// GetCustomCABundle returns the custom CA bundle's PEM bytes if the file was -func (c EnvConfig) getCustomCABundle(context.Context) (io.Reader, bool, error) { - if len(c.CustomCABundle) == 0 { - return nil, false, nil - } - - b, err := os.ReadFile(c.CustomCABundle) - if err != nil { - return nil, false, err - } - return bytes.NewReader(b), true, nil -} - -// GetIgnoreConfiguredEndpoints is used in knowing when to disable configured -// endpoints feature. -func (c EnvConfig) GetIgnoreConfiguredEndpoints(context.Context) (bool, bool, error) { - if c.IgnoreConfiguredEndpoints == nil { - return false, false, nil - } - - return *c.IgnoreConfiguredEndpoints, true, nil -} - -func (c EnvConfig) getBaseEndpoint(context.Context) (string, bool, error) { - return c.BaseEndpoint, len(c.BaseEndpoint) > 0, nil -} - -// GetServiceBaseEndpoint is used to retrieve a normalized SDK ID for use -// with configured endpoints. -func (c EnvConfig) GetServiceBaseEndpoint(ctx context.Context, sdkID string) (string, bool, error) { - if endpt := os.Getenv(fmt.Sprintf("%s_%s", awsEndpointURLEnv, normalizeEnv(sdkID))); endpt != "" { - return endpt, true, nil - } - return "", false, nil -} - -func normalizeEnv(sdkID string) string { - upper := strings.ToUpper(sdkID) - return strings.ReplaceAll(upper, " ", "_") -} - -// GetS3UseARNRegion returns whether to allow ARNs to direct the region -// the S3 client's requests are sent to. -func (c EnvConfig) GetS3UseARNRegion(ctx context.Context) (value, ok bool, err error) { - if c.S3UseARNRegion == nil { - return false, false, nil - } - - return *c.S3UseARNRegion, true, nil -} - -// GetS3DisableMultiRegionAccessPoints returns whether to disable multi-region access point -// support for the S3 client. -func (c EnvConfig) GetS3DisableMultiRegionAccessPoints(ctx context.Context) (value, ok bool, err error) { - if c.S3DisableMultiRegionAccessPoints == nil { - return false, false, nil - } - - return *c.S3DisableMultiRegionAccessPoints, true, nil -} - -// GetUseDualStackEndpoint returns whether the service's dual-stack endpoint should be -// used for requests. -func (c EnvConfig) GetUseDualStackEndpoint(ctx context.Context) (value aws.DualStackEndpointState, found bool, err error) { - if c.UseDualStackEndpoint == aws.DualStackEndpointStateUnset { - return aws.DualStackEndpointStateUnset, false, nil - } - - return c.UseDualStackEndpoint, true, nil -} - -// GetUseFIPSEndpoint returns whether the service's FIPS endpoint should be -// used for requests. -func (c EnvConfig) GetUseFIPSEndpoint(ctx context.Context) (value aws.FIPSEndpointState, found bool, err error) { - if c.UseFIPSEndpoint == aws.FIPSEndpointStateUnset { - return aws.FIPSEndpointStateUnset, false, nil - } - - return c.UseFIPSEndpoint, true, nil -} - -func setStringFromEnvVal(dst *string, keys []string) { - for _, k := range keys { - if v := os.Getenv(k); len(v) > 0 { - *dst = v - break - } - } -} - -func setIntFromEnvVal(dst *int, keys []string) error { - for _, k := range keys { - if v := os.Getenv(k); len(v) > 0 { - i, err := strconv.ParseInt(v, 10, 64) - if err != nil { - return fmt.Errorf("invalid value %s=%s, %w", k, v, err) - } - *dst = int(i) - break - } - } - - return nil -} - -func setBoolPtrFromEnvVal(dst **bool, keys []string) error { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue - } - - if *dst == nil { - *dst = new(bool) - } - - switch { - case strings.EqualFold(value, "false"): - **dst = false - case strings.EqualFold(value, "true"): - **dst = true - default: - return fmt.Errorf( - "invalid value for environment variable, %s=%s, need true or false", - k, value) - } - break - } - - return nil -} - -func setInt64PtrFromEnvVal(dst **int64, keys []string, max int64) error { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue - } - - v, err := strconv.ParseInt(value, 10, 64) - if err != nil { - return fmt.Errorf("invalid value for env var, %s=%s, need int64", k, value) - } else if v < 0 || v > max { - return fmt.Errorf("invalid range for env var min request compression size bytes %q, must be within 0 and 10485760 inclusively", v) - } - if *dst == nil { - *dst = new(int64) - } - - **dst = v - break - } - - return nil -} - -func setEndpointDiscoveryTypeFromEnvVal(dst *aws.EndpointDiscoveryEnableState, keys []string) error { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue // skip if empty - } - - switch { - case strings.EqualFold(value, endpointDiscoveryDisabled): - *dst = aws.EndpointDiscoveryDisabled - case strings.EqualFold(value, endpointDiscoveryEnabled): - *dst = aws.EndpointDiscoveryEnabled - case strings.EqualFold(value, endpointDiscoveryAuto): - *dst = aws.EndpointDiscoveryAuto - default: - return fmt.Errorf( - "invalid value for environment variable, %s=%s, need true, false or auto", - k, value) - } - } - return nil -} - -func setUseDualStackEndpointFromEnvVal(dst *aws.DualStackEndpointState, keys []string) error { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue // skip if empty - } - - switch { - case strings.EqualFold(value, "true"): - *dst = aws.DualStackEndpointStateEnabled - case strings.EqualFold(value, "false"): - *dst = aws.DualStackEndpointStateDisabled - default: - return fmt.Errorf( - "invalid value for environment variable, %s=%s, need true, false", - k, value) - } - } - return nil -} - -func setUseFIPSEndpointFromEnvVal(dst *aws.FIPSEndpointState, keys []string) error { - for _, k := range keys { - value := os.Getenv(k) - if len(value) == 0 { - continue // skip if empty - } - - switch { - case strings.EqualFold(value, "true"): - *dst = aws.FIPSEndpointStateEnabled - case strings.EqualFold(value, "false"): - *dst = aws.FIPSEndpointStateDisabled - default: - return fmt.Errorf( - "invalid value for environment variable, %s=%s, need true, false", - k, value) - } - } - return nil -} - -// GetEnableEndpointDiscovery returns resolved value for EnableEndpointDiscovery env variable setting. -func (c EnvConfig) GetEnableEndpointDiscovery(ctx context.Context) (value aws.EndpointDiscoveryEnableState, found bool, err error) { - if c.EnableEndpointDiscovery == aws.EndpointDiscoveryUnset { - return aws.EndpointDiscoveryUnset, false, nil - } - - return c.EnableEndpointDiscovery, true, nil -} - -// GetEC2IMDSClientEnableState implements a EC2IMDSClientEnableState options resolver interface. -func (c EnvConfig) GetEC2IMDSClientEnableState() (imds.ClientEnableState, bool, error) { - if c.EC2IMDSClientEnableState == imds.ClientDefaultEnableState { - return imds.ClientDefaultEnableState, false, nil - } - - return c.EC2IMDSClientEnableState, true, nil -} - -// GetEC2IMDSEndpointMode implements a EC2IMDSEndpointMode option resolver interface. -func (c EnvConfig) GetEC2IMDSEndpointMode() (imds.EndpointModeState, bool, error) { - if c.EC2IMDSEndpointMode == imds.EndpointModeStateUnset { - return imds.EndpointModeStateUnset, false, nil - } - - return c.EC2IMDSEndpointMode, true, nil -} - -// GetEC2IMDSEndpoint implements a EC2IMDSEndpoint option resolver interface. -func (c EnvConfig) GetEC2IMDSEndpoint() (string, bool, error) { - if len(c.EC2IMDSEndpoint) == 0 { - return "", false, nil - } - - return c.EC2IMDSEndpoint, true, nil -} - -// GetEC2IMDSV1FallbackDisabled implements an EC2IMDSV1FallbackDisabled option -// resolver interface. -func (c EnvConfig) GetEC2IMDSV1FallbackDisabled() (bool, bool) { - if c.EC2IMDSv1Disabled == nil { - return false, false - } - - return *c.EC2IMDSv1Disabled, true -} - -// GetS3DisableExpressAuth returns the configured value for -// [EnvConfig.S3DisableExpressAuth]. -func (c EnvConfig) GetS3DisableExpressAuth() (value, ok bool) { - if c.S3DisableExpressAuth == nil { - return false, false - } - - return *c.S3DisableExpressAuth, true -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/generate.go b/vendor/github.com/aws/aws-sdk-go-v2/config/generate.go deleted file mode 100644 index 654a7a7..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/generate.go +++ /dev/null @@ -1,4 +0,0 @@ -package config - -//go:generate go run -tags codegen ./codegen -output=provider_assert_test.go -//go:generate gofmt -s -w ./ diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go deleted file mode 100644 index 089369e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package config - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.29.5" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go b/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go deleted file mode 100644 index 0810ecf..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go +++ /dev/null @@ -1,1209 +0,0 @@ -package config - -import ( - "context" - "io" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds" - "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds" - "github.com/aws/aws-sdk-go-v2/credentials/processcreds" - "github.com/aws/aws-sdk-go-v2/credentials/ssocreds" - "github.com/aws/aws-sdk-go-v2/credentials/stscreds" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - smithybearer "github.com/aws/smithy-go/auth/bearer" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" -) - -// LoadOptionsFunc is a type alias for LoadOptions functional option -type LoadOptionsFunc func(*LoadOptions) error - -// LoadOptions are discrete set of options that are valid for loading the -// configuration -type LoadOptions struct { - - // Region is the region to send requests to. - Region string - - // Credentials object to use when signing requests. - Credentials aws.CredentialsProvider - - // Token provider for authentication operations with bearer authentication. - BearerAuthTokenProvider smithybearer.TokenProvider - - // HTTPClient the SDK's API clients will use to invoke HTTP requests. - HTTPClient HTTPClient - - // EndpointResolver that can be used to provide or override an endpoint for - // the given service and region. - // - // See the `aws.EndpointResolver` documentation on usage. - // - // Deprecated: See EndpointResolverWithOptions - EndpointResolver aws.EndpointResolver - - // EndpointResolverWithOptions that can be used to provide or override an - // endpoint for the given service and region. - // - // See the `aws.EndpointResolverWithOptions` documentation on usage. - EndpointResolverWithOptions aws.EndpointResolverWithOptions - - // RetryMaxAttempts specifies the maximum number attempts an API client - // will call an operation that fails with a retryable error. - // - // This value will only be used if Retryer option is nil. - RetryMaxAttempts int - - // RetryMode specifies the retry model the API client will be created with. - // - // This value will only be used if Retryer option is nil. - RetryMode aws.RetryMode - - // Retryer is a function that provides a Retryer implementation. A Retryer - // guides how HTTP requests should be retried in case of recoverable - // failures. - // - // If not nil, RetryMaxAttempts, and RetryMode will be ignored. - Retryer func() aws.Retryer - - // APIOptions provides the set of middleware mutations modify how the API - // client requests will be handled. This is useful for adding additional - // tracing data to a request, or changing behavior of the SDK's client. - APIOptions []func(*middleware.Stack) error - - // Logger writer interface to write logging messages to. - Logger logging.Logger - - // ClientLogMode is used to configure the events that will be sent to the - // configured logger. This can be used to configure the logging of signing, - // retries, request, and responses of the SDK clients. - // - // See the ClientLogMode type documentation for the complete set of logging - // modes and available configuration. - ClientLogMode *aws.ClientLogMode - - // SharedConfigProfile is the profile to be used when loading the SharedConfig - SharedConfigProfile string - - // SharedConfigFiles is the slice of custom shared config files to use when - // loading the SharedConfig. A non-default profile used within config file - // must have name defined with prefix 'profile '. eg [profile xyz] - // indicates a profile with name 'xyz'. To read more on the format of the - // config file, please refer the documentation at - // https://docs.aws.amazon.com/credref/latest/refdocs/file-format.html#file-format-config - // - // If duplicate profiles are provided within the same, or across multiple - // shared config files, the next parsed profile will override only the - // properties that conflict with the previously defined profile. Note that - // if duplicate profiles are provided within the SharedCredentialsFiles and - // SharedConfigFiles, the properties defined in shared credentials file - // take precedence. - SharedConfigFiles []string - - // SharedCredentialsFile is the slice of custom shared credentials files to - // use when loading the SharedConfig. The profile name used within - // credentials file must not prefix 'profile '. eg [xyz] indicates a - // profile with name 'xyz'. Profile declared as [profile xyz] will be - // ignored. To read more on the format of the credentials file, please - // refer the documentation at - // https://docs.aws.amazon.com/credref/latest/refdocs/file-format.html#file-format-creds - // - // If duplicate profiles are provided with a same, or across multiple - // shared credentials files, the next parsed profile will override only - // properties that conflict with the previously defined profile. Note that - // if duplicate profiles are provided within the SharedCredentialsFiles and - // SharedConfigFiles, the properties defined in shared credentials file - // take precedence. - SharedCredentialsFiles []string - - // CustomCABundle is CA bundle PEM bytes reader - CustomCABundle io.Reader - - // DefaultRegion is the fall back region, used if a region was not resolved - // from other sources - DefaultRegion string - - // UseEC2IMDSRegion indicates if SDK should retrieve the region - // from the EC2 Metadata service - UseEC2IMDSRegion *UseEC2IMDSRegion - - // CredentialsCacheOptions is a function for setting the - // aws.CredentialsCacheOptions - CredentialsCacheOptions func(*aws.CredentialsCacheOptions) - - // BearerAuthTokenCacheOptions is a function for setting the smithy-go - // auth/bearer#TokenCacheOptions - BearerAuthTokenCacheOptions func(*smithybearer.TokenCacheOptions) - - // SSOTokenProviderOptions is a function for setting the - // credentials/ssocreds.SSOTokenProviderOptions - SSOTokenProviderOptions func(*ssocreds.SSOTokenProviderOptions) - - // ProcessCredentialOptions is a function for setting - // the processcreds.Options - ProcessCredentialOptions func(*processcreds.Options) - - // EC2RoleCredentialOptions is a function for setting - // the ec2rolecreds.Options - EC2RoleCredentialOptions func(*ec2rolecreds.Options) - - // EndpointCredentialOptions is a function for setting - // the endpointcreds.Options - EndpointCredentialOptions func(*endpointcreds.Options) - - // WebIdentityRoleCredentialOptions is a function for setting - // the stscreds.WebIdentityRoleOptions - WebIdentityRoleCredentialOptions func(*stscreds.WebIdentityRoleOptions) - - // AssumeRoleCredentialOptions is a function for setting the - // stscreds.AssumeRoleOptions - AssumeRoleCredentialOptions func(*stscreds.AssumeRoleOptions) - - // SSOProviderOptions is a function for setting - // the ssocreds.Options - SSOProviderOptions func(options *ssocreds.Options) - - // LogConfigurationWarnings when set to true, enables logging - // configuration warnings - LogConfigurationWarnings *bool - - // S3UseARNRegion specifies if the S3 service should allow ARNs to direct - // the region, the client's requests are sent to. - S3UseARNRegion *bool - - // S3DisableMultiRegionAccessPoints specifies if the S3 service should disable - // the S3 Multi-Region access points feature. - S3DisableMultiRegionAccessPoints *bool - - // EnableEndpointDiscovery specifies if endpoint discovery is enable for - // the client. - EnableEndpointDiscovery aws.EndpointDiscoveryEnableState - - // Specifies if the EC2 IMDS service client is enabled. - // - // AWS_EC2_METADATA_DISABLED=true - EC2IMDSClientEnableState imds.ClientEnableState - - // Specifies the EC2 Instance Metadata Service default endpoint selection - // mode (IPv4 or IPv6) - EC2IMDSEndpointMode imds.EndpointModeState - - // Specifies the EC2 Instance Metadata Service endpoint to use. If - // specified it overrides EC2IMDSEndpointMode. - EC2IMDSEndpoint string - - // Specifies that SDK clients must resolve a dual-stack endpoint for - // services. - UseDualStackEndpoint aws.DualStackEndpointState - - // Specifies that SDK clients must resolve a FIPS endpoint for - // services. - UseFIPSEndpoint aws.FIPSEndpointState - - // Specifies the SDK configuration mode for defaults. - DefaultsModeOptions DefaultsModeOptions - - // The sdk app ID retrieved from env var or shared config to be added to request user agent header - AppID string - - // Specifies whether an operation request could be compressed - DisableRequestCompression *bool - - // The inclusive min bytes of a request body that could be compressed - RequestMinCompressSizeBytes *int64 - - // Whether S3 Express auth is disabled. - S3DisableExpressAuth *bool - - // Whether account id should be built into endpoint resolution - AccountIDEndpointMode aws.AccountIDEndpointMode - - // Specify if request checksum should be calculated - RequestChecksumCalculation aws.RequestChecksumCalculation - - // Specifies if response checksum should be validated - ResponseChecksumValidation aws.ResponseChecksumValidation - - // Service endpoint override. This value is not necessarily final and is - // passed to the service's EndpointResolverV2 for further delegation. - BaseEndpoint string -} - -func (o LoadOptions) getDefaultsMode(ctx context.Context) (aws.DefaultsMode, bool, error) { - if len(o.DefaultsModeOptions.Mode) == 0 { - return "", false, nil - } - return o.DefaultsModeOptions.Mode, true, nil -} - -// GetRetryMaxAttempts returns the RetryMaxAttempts if specified in the -// LoadOptions and not 0. -func (o LoadOptions) GetRetryMaxAttempts(ctx context.Context) (int, bool, error) { - if o.RetryMaxAttempts == 0 { - return 0, false, nil - } - return o.RetryMaxAttempts, true, nil -} - -// GetRetryMode returns the RetryMode specified in the LoadOptions. -func (o LoadOptions) GetRetryMode(ctx context.Context) (aws.RetryMode, bool, error) { - if len(o.RetryMode) == 0 { - return "", false, nil - } - return o.RetryMode, true, nil -} - -func (o LoadOptions) getDefaultsModeIMDSClient(ctx context.Context) (*imds.Client, bool, error) { - if o.DefaultsModeOptions.IMDSClient == nil { - return nil, false, nil - } - return o.DefaultsModeOptions.IMDSClient, true, nil -} - -// getRegion returns Region from config's LoadOptions -func (o LoadOptions) getRegion(ctx context.Context) (string, bool, error) { - if len(o.Region) == 0 { - return "", false, nil - } - - return o.Region, true, nil -} - -// getAppID returns AppID from config's LoadOptions -func (o LoadOptions) getAppID(ctx context.Context) (string, bool, error) { - return o.AppID, len(o.AppID) > 0, nil -} - -// getDisableRequestCompression returns DisableRequestCompression from config's LoadOptions -func (o LoadOptions) getDisableRequestCompression(ctx context.Context) (bool, bool, error) { - if o.DisableRequestCompression == nil { - return false, false, nil - } - return *o.DisableRequestCompression, true, nil -} - -// getRequestMinCompressSizeBytes returns RequestMinCompressSizeBytes from config's LoadOptions -func (o LoadOptions) getRequestMinCompressSizeBytes(ctx context.Context) (int64, bool, error) { - if o.RequestMinCompressSizeBytes == nil { - return 0, false, nil - } - return *o.RequestMinCompressSizeBytes, true, nil -} - -func (o LoadOptions) getAccountIDEndpointMode(ctx context.Context) (aws.AccountIDEndpointMode, bool, error) { - return o.AccountIDEndpointMode, len(o.AccountIDEndpointMode) > 0, nil -} - -func (o LoadOptions) getRequestChecksumCalculation(ctx context.Context) (aws.RequestChecksumCalculation, bool, error) { - return o.RequestChecksumCalculation, o.RequestChecksumCalculation > 0, nil -} - -func (o LoadOptions) getResponseChecksumValidation(ctx context.Context) (aws.ResponseChecksumValidation, bool, error) { - return o.ResponseChecksumValidation, o.ResponseChecksumValidation > 0, nil -} - -func (o LoadOptions) getBaseEndpoint(context.Context) (string, bool, error) { - return o.BaseEndpoint, o.BaseEndpoint != "", nil -} - -// GetServiceBaseEndpoint satisfies (internal/configsources).ServiceBaseEndpointProvider. -// -// The sdkID value is unused because LoadOptions only supports setting a GLOBAL -// endpoint override. In-code, per-service endpoint overrides are performed via -// functional options in service client space. -func (o LoadOptions) GetServiceBaseEndpoint(context.Context, string) (string, bool, error) { - return o.BaseEndpoint, o.BaseEndpoint != "", nil -} - -// WithRegion is a helper function to construct functional options -// that sets Region on config's LoadOptions. Setting the region to -// an empty string, will result in the region value being ignored. -// If multiple WithRegion calls are made, the last call overrides -// the previous call values. -func WithRegion(v string) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.Region = v - return nil - } -} - -// WithAppID is a helper function to construct functional options -// that sets AppID on config's LoadOptions. -func WithAppID(ID string) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.AppID = ID - return nil - } -} - -// WithDisableRequestCompression is a helper function to construct functional options -// that sets DisableRequestCompression on config's LoadOptions. -func WithDisableRequestCompression(DisableRequestCompression *bool) LoadOptionsFunc { - return func(o *LoadOptions) error { - if DisableRequestCompression == nil { - return nil - } - o.DisableRequestCompression = DisableRequestCompression - return nil - } -} - -// WithRequestMinCompressSizeBytes is a helper function to construct functional options -// that sets RequestMinCompressSizeBytes on config's LoadOptions. -func WithRequestMinCompressSizeBytes(RequestMinCompressSizeBytes *int64) LoadOptionsFunc { - return func(o *LoadOptions) error { - if RequestMinCompressSizeBytes == nil { - return nil - } - o.RequestMinCompressSizeBytes = RequestMinCompressSizeBytes - return nil - } -} - -// WithAccountIDEndpointMode is a helper function to construct functional options -// that sets AccountIDEndpointMode on config's LoadOptions -func WithAccountIDEndpointMode(m aws.AccountIDEndpointMode) LoadOptionsFunc { - return func(o *LoadOptions) error { - if m != "" { - o.AccountIDEndpointMode = m - } - return nil - } -} - -// WithRequestChecksumCalculation is a helper function to construct functional options -// that sets RequestChecksumCalculation on config's LoadOptions -func WithRequestChecksumCalculation(c aws.RequestChecksumCalculation) LoadOptionsFunc { - return func(o *LoadOptions) error { - if c > 0 { - o.RequestChecksumCalculation = c - } - return nil - } -} - -// WithResponseChecksumValidation is a helper function to construct functional options -// that sets ResponseChecksumValidation on config's LoadOptions -func WithResponseChecksumValidation(v aws.ResponseChecksumValidation) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.ResponseChecksumValidation = v - return nil - } -} - -// getDefaultRegion returns DefaultRegion from config's LoadOptions -func (o LoadOptions) getDefaultRegion(ctx context.Context) (string, bool, error) { - if len(o.DefaultRegion) == 0 { - return "", false, nil - } - - return o.DefaultRegion, true, nil -} - -// WithDefaultRegion is a helper function to construct functional options -// that sets a DefaultRegion on config's LoadOptions. Setting the default -// region to an empty string, will result in the default region value -// being ignored. If multiple WithDefaultRegion calls are made, the last -// call overrides the previous call values. Note that both WithRegion and -// WithEC2IMDSRegion call takes precedence over WithDefaultRegion call -// when resolving region. -func WithDefaultRegion(v string) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.DefaultRegion = v - return nil - } -} - -// getSharedConfigProfile returns SharedConfigProfile from config's LoadOptions -func (o LoadOptions) getSharedConfigProfile(ctx context.Context) (string, bool, error) { - if len(o.SharedConfigProfile) == 0 { - return "", false, nil - } - - return o.SharedConfigProfile, true, nil -} - -// WithSharedConfigProfile is a helper function to construct functional options -// that sets SharedConfigProfile on config's LoadOptions. Setting the shared -// config profile to an empty string, will result in the shared config profile -// value being ignored. -// If multiple WithSharedConfigProfile calls are made, the last call overrides -// the previous call values. -func WithSharedConfigProfile(v string) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.SharedConfigProfile = v - return nil - } -} - -// getSharedConfigFiles returns SharedConfigFiles set on config's LoadOptions -func (o LoadOptions) getSharedConfigFiles(ctx context.Context) ([]string, bool, error) { - if o.SharedConfigFiles == nil { - return nil, false, nil - } - - return o.SharedConfigFiles, true, nil -} - -// WithSharedConfigFiles is a helper function to construct functional options -// that sets slice of SharedConfigFiles on config's LoadOptions. -// Setting the shared config files to an nil string slice, will result in the -// shared config files value being ignored. -// If multiple WithSharedConfigFiles calls are made, the last call overrides -// the previous call values. -func WithSharedConfigFiles(v []string) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.SharedConfigFiles = v - return nil - } -} - -// getSharedCredentialsFiles returns SharedCredentialsFiles set on config's LoadOptions -func (o LoadOptions) getSharedCredentialsFiles(ctx context.Context) ([]string, bool, error) { - if o.SharedCredentialsFiles == nil { - return nil, false, nil - } - - return o.SharedCredentialsFiles, true, nil -} - -// WithSharedCredentialsFiles is a helper function to construct functional options -// that sets slice of SharedCredentialsFiles on config's LoadOptions. -// Setting the shared credentials files to an nil string slice, will result in the -// shared credentials files value being ignored. -// If multiple WithSharedCredentialsFiles calls are made, the last call overrides -// the previous call values. -func WithSharedCredentialsFiles(v []string) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.SharedCredentialsFiles = v - return nil - } -} - -// getCustomCABundle returns CustomCABundle from LoadOptions -func (o LoadOptions) getCustomCABundle(ctx context.Context) (io.Reader, bool, error) { - if o.CustomCABundle == nil { - return nil, false, nil - } - - return o.CustomCABundle, true, nil -} - -// WithCustomCABundle is a helper function to construct functional options -// that sets CustomCABundle on config's LoadOptions. Setting the custom CA Bundle -// to nil will result in custom CA Bundle value being ignored. -// If multiple WithCustomCABundle calls are made, the last call overrides the -// previous call values. -func WithCustomCABundle(v io.Reader) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.CustomCABundle = v - return nil - } -} - -// UseEC2IMDSRegion provides a regionProvider that retrieves the region -// from the EC2 Metadata service. -type UseEC2IMDSRegion struct { - // If unset will default to generic EC2 IMDS client. - Client *imds.Client -} - -// getRegion attempts to retrieve the region from EC2 Metadata service. -func (p *UseEC2IMDSRegion) getRegion(ctx context.Context) (string, bool, error) { - if ctx == nil { - ctx = context.Background() - } - - client := p.Client - if client == nil { - client = imds.New(imds.Options{}) - } - - result, err := client.GetRegion(ctx, nil) - if err != nil { - return "", false, err - } - if len(result.Region) != 0 { - return result.Region, true, nil - } - return "", false, nil -} - -// getEC2IMDSRegion returns the value of EC2 IMDS region. -func (o LoadOptions) getEC2IMDSRegion(ctx context.Context) (string, bool, error) { - if o.UseEC2IMDSRegion == nil { - return "", false, nil - } - - return o.UseEC2IMDSRegion.getRegion(ctx) -} - -// WithEC2IMDSRegion is a helper function to construct functional options -// that enables resolving EC2IMDS region. The function takes -// in a UseEC2IMDSRegion functional option, and can be used to set the -// EC2IMDS client which will be used to resolve EC2IMDSRegion. -// If no functional option is provided, an EC2IMDS client is built and used -// by the resolver. If multiple WithEC2IMDSRegion calls are made, the last -// call overrides the previous call values. Note that the WithRegion calls takes -// precedence over WithEC2IMDSRegion when resolving region. -func WithEC2IMDSRegion(fnOpts ...func(o *UseEC2IMDSRegion)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.UseEC2IMDSRegion = &UseEC2IMDSRegion{} - - for _, fn := range fnOpts { - fn(o.UseEC2IMDSRegion) - } - return nil - } -} - -// getCredentialsProvider returns the credentials value -func (o LoadOptions) getCredentialsProvider(ctx context.Context) (aws.CredentialsProvider, bool, error) { - if o.Credentials == nil { - return nil, false, nil - } - - return o.Credentials, true, nil -} - -// WithCredentialsProvider is a helper function to construct functional options -// that sets Credential provider value on config's LoadOptions. If credentials -// provider is set to nil, the credentials provider value will be ignored. -// If multiple WithCredentialsProvider calls are made, the last call overrides -// the previous call values. -func WithCredentialsProvider(v aws.CredentialsProvider) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.Credentials = v - return nil - } -} - -// getCredentialsCacheOptionsProvider returns the wrapped function to set aws.CredentialsCacheOptions -func (o LoadOptions) getCredentialsCacheOptions(ctx context.Context) (func(*aws.CredentialsCacheOptions), bool, error) { - if o.CredentialsCacheOptions == nil { - return nil, false, nil - } - - return o.CredentialsCacheOptions, true, nil -} - -// WithCredentialsCacheOptions is a helper function to construct functional -// options that sets a function to modify the aws.CredentialsCacheOptions the -// aws.CredentialsCache will be configured with, if the CredentialsCache is used -// by the configuration loader. -// -// If multiple WithCredentialsCacheOptions calls are made, the last call -// overrides the previous call values. -func WithCredentialsCacheOptions(v func(*aws.CredentialsCacheOptions)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.CredentialsCacheOptions = v - return nil - } -} - -// getBearerAuthTokenProvider returns the credentials value -func (o LoadOptions) getBearerAuthTokenProvider(ctx context.Context) (smithybearer.TokenProvider, bool, error) { - if o.BearerAuthTokenProvider == nil { - return nil, false, nil - } - - return o.BearerAuthTokenProvider, true, nil -} - -// WithBearerAuthTokenProvider is a helper function to construct functional options -// that sets Credential provider value on config's LoadOptions. If credentials -// provider is set to nil, the credentials provider value will be ignored. -// If multiple WithBearerAuthTokenProvider calls are made, the last call overrides -// the previous call values. -func WithBearerAuthTokenProvider(v smithybearer.TokenProvider) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.BearerAuthTokenProvider = v - return nil - } -} - -// getBearerAuthTokenCacheOptionsProvider returns the wrapped function to set smithybearer.TokenCacheOptions -func (o LoadOptions) getBearerAuthTokenCacheOptions(ctx context.Context) (func(*smithybearer.TokenCacheOptions), bool, error) { - if o.BearerAuthTokenCacheOptions == nil { - return nil, false, nil - } - - return o.BearerAuthTokenCacheOptions, true, nil -} - -// WithBearerAuthTokenCacheOptions is a helper function to construct functional options -// that sets a function to modify the TokenCacheOptions the smithy-go -// auth/bearer#TokenCache will be configured with, if the TokenCache is used by -// the configuration loader. -// -// If multiple WithBearerAuthTokenCacheOptions calls are made, the last call overrides -// the previous call values. -func WithBearerAuthTokenCacheOptions(v func(*smithybearer.TokenCacheOptions)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.BearerAuthTokenCacheOptions = v - return nil - } -} - -// getSSOTokenProviderOptionsProvider returns the wrapped function to set smithybearer.TokenCacheOptions -func (o LoadOptions) getSSOTokenProviderOptions(ctx context.Context) (func(*ssocreds.SSOTokenProviderOptions), bool, error) { - if o.SSOTokenProviderOptions == nil { - return nil, false, nil - } - - return o.SSOTokenProviderOptions, true, nil -} - -// WithSSOTokenProviderOptions is a helper function to construct functional -// options that sets a function to modify the SSOtokenProviderOptions the SDK's -// credentials/ssocreds#SSOProvider will be configured with, if the -// SSOTokenProvider is used by the configuration loader. -// -// If multiple WithSSOTokenProviderOptions calls are made, the last call overrides -// the previous call values. -func WithSSOTokenProviderOptions(v func(*ssocreds.SSOTokenProviderOptions)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.SSOTokenProviderOptions = v - return nil - } -} - -// getProcessCredentialOptions returns the wrapped function to set processcreds.Options -func (o LoadOptions) getProcessCredentialOptions(ctx context.Context) (func(*processcreds.Options), bool, error) { - if o.ProcessCredentialOptions == nil { - return nil, false, nil - } - - return o.ProcessCredentialOptions, true, nil -} - -// WithProcessCredentialOptions is a helper function to construct functional options -// that sets a function to use processcreds.Options on config's LoadOptions. -// If process credential options is set to nil, the process credential value will -// be ignored. If multiple WithProcessCredentialOptions calls are made, the last call -// overrides the previous call values. -func WithProcessCredentialOptions(v func(*processcreds.Options)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.ProcessCredentialOptions = v - return nil - } -} - -// getEC2RoleCredentialOptions returns the wrapped function to set the ec2rolecreds.Options -func (o LoadOptions) getEC2RoleCredentialOptions(ctx context.Context) (func(*ec2rolecreds.Options), bool, error) { - if o.EC2RoleCredentialOptions == nil { - return nil, false, nil - } - - return o.EC2RoleCredentialOptions, true, nil -} - -// WithEC2RoleCredentialOptions is a helper function to construct functional options -// that sets a function to use ec2rolecreds.Options on config's LoadOptions. If -// EC2 role credential options is set to nil, the EC2 role credential options value -// will be ignored. If multiple WithEC2RoleCredentialOptions calls are made, -// the last call overrides the previous call values. -func WithEC2RoleCredentialOptions(v func(*ec2rolecreds.Options)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.EC2RoleCredentialOptions = v - return nil - } -} - -// getEndpointCredentialOptions returns the wrapped function to set endpointcreds.Options -func (o LoadOptions) getEndpointCredentialOptions(context.Context) (func(*endpointcreds.Options), bool, error) { - if o.EndpointCredentialOptions == nil { - return nil, false, nil - } - - return o.EndpointCredentialOptions, true, nil -} - -// WithEndpointCredentialOptions is a helper function to construct functional options -// that sets a function to use endpointcreds.Options on config's LoadOptions. If -// endpoint credential options is set to nil, the endpoint credential options -// value will be ignored. If multiple WithEndpointCredentialOptions calls are made, -// the last call overrides the previous call values. -func WithEndpointCredentialOptions(v func(*endpointcreds.Options)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.EndpointCredentialOptions = v - return nil - } -} - -// getWebIdentityRoleCredentialOptions returns the wrapped function -func (o LoadOptions) getWebIdentityRoleCredentialOptions(context.Context) (func(*stscreds.WebIdentityRoleOptions), bool, error) { - if o.WebIdentityRoleCredentialOptions == nil { - return nil, false, nil - } - - return o.WebIdentityRoleCredentialOptions, true, nil -} - -// WithWebIdentityRoleCredentialOptions is a helper function to construct -// functional options that sets a function to use stscreds.WebIdentityRoleOptions -// on config's LoadOptions. If web identity role credentials options is set to nil, -// the web identity role credentials value will be ignored. If multiple -// WithWebIdentityRoleCredentialOptions calls are made, the last call -// overrides the previous call values. -func WithWebIdentityRoleCredentialOptions(v func(*stscreds.WebIdentityRoleOptions)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.WebIdentityRoleCredentialOptions = v - return nil - } -} - -// getAssumeRoleCredentialOptions returns AssumeRoleCredentialOptions from LoadOptions -func (o LoadOptions) getAssumeRoleCredentialOptions(context.Context) (func(options *stscreds.AssumeRoleOptions), bool, error) { - if o.AssumeRoleCredentialOptions == nil { - return nil, false, nil - } - - return o.AssumeRoleCredentialOptions, true, nil -} - -// WithAssumeRoleCredentialOptions is a helper function to construct -// functional options that sets a function to use stscreds.AssumeRoleOptions -// on config's LoadOptions. If assume role credentials options is set to nil, -// the assume role credentials value will be ignored. If multiple -// WithAssumeRoleCredentialOptions calls are made, the last call overrides -// the previous call values. -func WithAssumeRoleCredentialOptions(v func(*stscreds.AssumeRoleOptions)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.AssumeRoleCredentialOptions = v - return nil - } -} - -func (o LoadOptions) getHTTPClient(ctx context.Context) (HTTPClient, bool, error) { - if o.HTTPClient == nil { - return nil, false, nil - } - - return o.HTTPClient, true, nil -} - -// WithHTTPClient is a helper function to construct functional options -// that sets HTTPClient on LoadOptions. If HTTPClient is set to nil, -// the HTTPClient value will be ignored. -// If multiple WithHTTPClient calls are made, the last call overrides -// the previous call values. -func WithHTTPClient(v HTTPClient) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.HTTPClient = v - return nil - } -} - -func (o LoadOptions) getAPIOptions(ctx context.Context) ([]func(*middleware.Stack) error, bool, error) { - if o.APIOptions == nil { - return nil, false, nil - } - - return o.APIOptions, true, nil -} - -// WithAPIOptions is a helper function to construct functional options -// that sets APIOptions on LoadOptions. If APIOptions is set to nil, the -// APIOptions value is ignored. If multiple WithAPIOptions calls are -// made, the last call overrides the previous call values. -func WithAPIOptions(v []func(*middleware.Stack) error) LoadOptionsFunc { - return func(o *LoadOptions) error { - if v == nil { - return nil - } - - o.APIOptions = append(o.APIOptions, v...) - return nil - } -} - -func (o LoadOptions) getRetryMaxAttempts(ctx context.Context) (int, bool, error) { - if o.RetryMaxAttempts == 0 { - return 0, false, nil - } - - return o.RetryMaxAttempts, true, nil -} - -// WithRetryMaxAttempts is a helper function to construct functional options that sets -// RetryMaxAttempts on LoadOptions. If RetryMaxAttempts is unset, the RetryMaxAttempts value is -// ignored. If multiple WithRetryMaxAttempts calls are made, the last call overrides -// the previous call values. -// -// Will be ignored of LoadOptions.Retryer or WithRetryer are used. -func WithRetryMaxAttempts(v int) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.RetryMaxAttempts = v - return nil - } -} - -func (o LoadOptions) getRetryMode(ctx context.Context) (aws.RetryMode, bool, error) { - if o.RetryMode == "" { - return "", false, nil - } - - return o.RetryMode, true, nil -} - -// WithRetryMode is a helper function to construct functional options that sets -// RetryMode on LoadOptions. If RetryMode is unset, the RetryMode value is -// ignored. If multiple WithRetryMode calls are made, the last call overrides -// the previous call values. -// -// Will be ignored of LoadOptions.Retryer or WithRetryer are used. -func WithRetryMode(v aws.RetryMode) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.RetryMode = v - return nil - } -} - -func (o LoadOptions) getRetryer(ctx context.Context) (func() aws.Retryer, bool, error) { - if o.Retryer == nil { - return nil, false, nil - } - - return o.Retryer, true, nil -} - -// WithRetryer is a helper function to construct functional options -// that sets Retryer on LoadOptions. If Retryer is set to nil, the -// Retryer value is ignored. If multiple WithRetryer calls are -// made, the last call overrides the previous call values. -func WithRetryer(v func() aws.Retryer) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.Retryer = v - return nil - } -} - -func (o LoadOptions) getEndpointResolver(ctx context.Context) (aws.EndpointResolver, bool, error) { - if o.EndpointResolver == nil { - return nil, false, nil - } - - return o.EndpointResolver, true, nil -} - -// WithEndpointResolver is a helper function to construct functional options -// that sets the EndpointResolver on LoadOptions. If the EndpointResolver is set to nil, -// the EndpointResolver value is ignored. If multiple WithEndpointResolver calls -// are made, the last call overrides the previous call values. -// -// Deprecated: The global endpoint resolution interface is deprecated. The API -// for endpoint resolution is now unique to each service and is set via the -// EndpointResolverV2 field on service client options. Use of -// WithEndpointResolver or WithEndpointResolverWithOptions will prevent you -// from using any endpoint-related service features released after the -// introduction of EndpointResolverV2. You may also encounter broken or -// unexpected behavior when using the old global interface with services that -// use many endpoint-related customizations such as S3. -func WithEndpointResolver(v aws.EndpointResolver) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.EndpointResolver = v - return nil - } -} - -func (o LoadOptions) getEndpointResolverWithOptions(ctx context.Context) (aws.EndpointResolverWithOptions, bool, error) { - if o.EndpointResolverWithOptions == nil { - return nil, false, nil - } - - return o.EndpointResolverWithOptions, true, nil -} - -// WithEndpointResolverWithOptions is a helper function to construct functional options -// that sets the EndpointResolverWithOptions on LoadOptions. If the EndpointResolverWithOptions is set to nil, -// the EndpointResolver value is ignored. If multiple WithEndpointResolver calls -// are made, the last call overrides the previous call values. -// -// Deprecated: The global endpoint resolution interface is deprecated. See -// deprecation docs on [WithEndpointResolver]. -func WithEndpointResolverWithOptions(v aws.EndpointResolverWithOptions) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.EndpointResolverWithOptions = v - return nil - } -} - -func (o LoadOptions) getLogger(ctx context.Context) (logging.Logger, bool, error) { - if o.Logger == nil { - return nil, false, nil - } - - return o.Logger, true, nil -} - -// WithLogger is a helper function to construct functional options -// that sets Logger on LoadOptions. If Logger is set to nil, the -// Logger value will be ignored. If multiple WithLogger calls are made, -// the last call overrides the previous call values. -func WithLogger(v logging.Logger) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.Logger = v - return nil - } -} - -func (o LoadOptions) getClientLogMode(ctx context.Context) (aws.ClientLogMode, bool, error) { - if o.ClientLogMode == nil { - return 0, false, nil - } - - return *o.ClientLogMode, true, nil -} - -// WithClientLogMode is a helper function to construct functional options -// that sets client log mode on LoadOptions. If client log mode is set to nil, -// the client log mode value will be ignored. If multiple WithClientLogMode calls are made, -// the last call overrides the previous call values. -func WithClientLogMode(v aws.ClientLogMode) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.ClientLogMode = &v - return nil - } -} - -func (o LoadOptions) getLogConfigurationWarnings(ctx context.Context) (v bool, found bool, err error) { - if o.LogConfigurationWarnings == nil { - return false, false, nil - } - return *o.LogConfigurationWarnings, true, nil -} - -// WithLogConfigurationWarnings is a helper function to construct -// functional options that can be used to set LogConfigurationWarnings -// on LoadOptions. -// -// If multiple WithLogConfigurationWarnings calls are made, the last call -// overrides the previous call values. -func WithLogConfigurationWarnings(v bool) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.LogConfigurationWarnings = &v - return nil - } -} - -// GetS3UseARNRegion returns whether to allow ARNs to direct the region -// the S3 client's requests are sent to. -func (o LoadOptions) GetS3UseARNRegion(ctx context.Context) (v bool, found bool, err error) { - if o.S3UseARNRegion == nil { - return false, false, nil - } - return *o.S3UseARNRegion, true, nil -} - -// WithS3UseARNRegion is a helper function to construct functional options -// that can be used to set S3UseARNRegion on LoadOptions. -// If multiple WithS3UseARNRegion calls are made, the last call overrides -// the previous call values. -func WithS3UseARNRegion(v bool) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.S3UseARNRegion = &v - return nil - } -} - -// GetS3DisableMultiRegionAccessPoints returns whether to disable -// the S3 multi-region access points feature. -func (o LoadOptions) GetS3DisableMultiRegionAccessPoints(ctx context.Context) (v bool, found bool, err error) { - if o.S3DisableMultiRegionAccessPoints == nil { - return false, false, nil - } - return *o.S3DisableMultiRegionAccessPoints, true, nil -} - -// WithS3DisableMultiRegionAccessPoints is a helper function to construct functional options -// that can be used to set S3DisableMultiRegionAccessPoints on LoadOptions. -// If multiple WithS3DisableMultiRegionAccessPoints calls are made, the last call overrides -// the previous call values. -func WithS3DisableMultiRegionAccessPoints(v bool) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.S3DisableMultiRegionAccessPoints = &v - return nil - } -} - -// GetEnableEndpointDiscovery returns if the EnableEndpointDiscovery flag is set. -func (o LoadOptions) GetEnableEndpointDiscovery(ctx context.Context) (value aws.EndpointDiscoveryEnableState, ok bool, err error) { - if o.EnableEndpointDiscovery == aws.EndpointDiscoveryUnset { - return aws.EndpointDiscoveryUnset, false, nil - } - return o.EnableEndpointDiscovery, true, nil -} - -// WithEndpointDiscovery is a helper function to construct functional options -// that can be used to enable endpoint discovery on LoadOptions for supported clients. -// If multiple WithEndpointDiscovery calls are made, the last call overrides -// the previous call values. -func WithEndpointDiscovery(v aws.EndpointDiscoveryEnableState) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.EnableEndpointDiscovery = v - return nil - } -} - -// getSSOProviderOptions returns AssumeRoleCredentialOptions from LoadOptions -func (o LoadOptions) getSSOProviderOptions(context.Context) (func(options *ssocreds.Options), bool, error) { - if o.SSOProviderOptions == nil { - return nil, false, nil - } - - return o.SSOProviderOptions, true, nil -} - -// WithSSOProviderOptions is a helper function to construct -// functional options that sets a function to use ssocreds.Options -// on config's LoadOptions. If the SSO credential provider options is set to nil, -// the sso provider options value will be ignored. If multiple -// WithSSOProviderOptions calls are made, the last call overrides -// the previous call values. -func WithSSOProviderOptions(v func(*ssocreds.Options)) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.SSOProviderOptions = v - return nil - } -} - -// GetEC2IMDSClientEnableState implements a EC2IMDSClientEnableState options resolver interface. -func (o LoadOptions) GetEC2IMDSClientEnableState() (imds.ClientEnableState, bool, error) { - if o.EC2IMDSClientEnableState == imds.ClientDefaultEnableState { - return imds.ClientDefaultEnableState, false, nil - } - - return o.EC2IMDSClientEnableState, true, nil -} - -// GetEC2IMDSEndpointMode implements a EC2IMDSEndpointMode option resolver interface. -func (o LoadOptions) GetEC2IMDSEndpointMode() (imds.EndpointModeState, bool, error) { - if o.EC2IMDSEndpointMode == imds.EndpointModeStateUnset { - return imds.EndpointModeStateUnset, false, nil - } - - return o.EC2IMDSEndpointMode, true, nil -} - -// GetEC2IMDSEndpoint implements a EC2IMDSEndpoint option resolver interface. -func (o LoadOptions) GetEC2IMDSEndpoint() (string, bool, error) { - if len(o.EC2IMDSEndpoint) == 0 { - return "", false, nil - } - - return o.EC2IMDSEndpoint, true, nil -} - -// WithEC2IMDSClientEnableState is a helper function to construct functional options that sets the EC2IMDSClientEnableState. -func WithEC2IMDSClientEnableState(v imds.ClientEnableState) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.EC2IMDSClientEnableState = v - return nil - } -} - -// WithEC2IMDSEndpointMode is a helper function to construct functional options that sets the EC2IMDSEndpointMode. -func WithEC2IMDSEndpointMode(v imds.EndpointModeState) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.EC2IMDSEndpointMode = v - return nil - } -} - -// WithEC2IMDSEndpoint is a helper function to construct functional options that sets the EC2IMDSEndpoint. -func WithEC2IMDSEndpoint(v string) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.EC2IMDSEndpoint = v - return nil - } -} - -// WithUseDualStackEndpoint is a helper function to construct -// functional options that can be used to set UseDualStackEndpoint on LoadOptions. -func WithUseDualStackEndpoint(v aws.DualStackEndpointState) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.UseDualStackEndpoint = v - return nil - } -} - -// GetUseDualStackEndpoint returns whether the service's dual-stack endpoint should be -// used for requests. -func (o LoadOptions) GetUseDualStackEndpoint(ctx context.Context) (value aws.DualStackEndpointState, found bool, err error) { - if o.UseDualStackEndpoint == aws.DualStackEndpointStateUnset { - return aws.DualStackEndpointStateUnset, false, nil - } - return o.UseDualStackEndpoint, true, nil -} - -// WithUseFIPSEndpoint is a helper function to construct -// functional options that can be used to set UseFIPSEndpoint on LoadOptions. -func WithUseFIPSEndpoint(v aws.FIPSEndpointState) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.UseFIPSEndpoint = v - return nil - } -} - -// GetUseFIPSEndpoint returns whether the service's FIPS endpoint should be -// used for requests. -func (o LoadOptions) GetUseFIPSEndpoint(ctx context.Context) (value aws.FIPSEndpointState, found bool, err error) { - if o.UseFIPSEndpoint == aws.FIPSEndpointStateUnset { - return aws.FIPSEndpointStateUnset, false, nil - } - return o.UseFIPSEndpoint, true, nil -} - -// WithDefaultsMode sets the SDK defaults configuration mode to the value provided. -// -// Zero or more functional options can be provided to provide configuration options for performing -// environment discovery when using aws.DefaultsModeAuto. -func WithDefaultsMode(mode aws.DefaultsMode, optFns ...func(options *DefaultsModeOptions)) LoadOptionsFunc { - do := DefaultsModeOptions{ - Mode: mode, - } - for _, fn := range optFns { - fn(&do) - } - return func(options *LoadOptions) error { - options.DefaultsModeOptions = do - return nil - } -} - -// GetS3DisableExpressAuth returns the configured value for -// [EnvConfig.S3DisableExpressAuth]. -func (o LoadOptions) GetS3DisableExpressAuth() (value, ok bool) { - if o.S3DisableExpressAuth == nil { - return false, false - } - - return *o.S3DisableExpressAuth, true -} - -// WithS3DisableExpressAuth sets [LoadOptions.S3DisableExpressAuth] -// to the value provided. -func WithS3DisableExpressAuth(v bool) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.S3DisableExpressAuth = &v - return nil - } -} - -// WithBaseEndpoint is a helper function to construct functional options that -// sets BaseEndpoint on config's LoadOptions. Empty values have no effect, and -// subsequent calls to this API override previous ones. -// -// This is an in-code setting, therefore, any value set using this hook takes -// precedence over and will override ALL environment and shared config -// directives that set endpoint URLs. Functional options on service clients -// have higher specificity, and functional options that modify the value of -// BaseEndpoint on a client will take precedence over this setting. -func WithBaseEndpoint(v string) LoadOptionsFunc { - return func(o *LoadOptions) error { - o.BaseEndpoint = v - return nil - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/local.go b/vendor/github.com/aws/aws-sdk-go-v2/config/local.go deleted file mode 100644 index b629137..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/local.go +++ /dev/null @@ -1,51 +0,0 @@ -package config - -import ( - "fmt" - "net" - "net/url" -) - -var lookupHostFn = net.LookupHost - -func isLoopbackHost(host string) (bool, error) { - ip := net.ParseIP(host) - if ip != nil { - return ip.IsLoopback(), nil - } - - // Host is not an ip, perform lookup - addrs, err := lookupHostFn(host) - if err != nil { - return false, err - } - if len(addrs) == 0 { - return false, fmt.Errorf("no addrs found for host, %s", host) - } - - for _, addr := range addrs { - if !net.ParseIP(addr).IsLoopback() { - return false, nil - } - } - - return true, nil -} - -func validateLocalURL(v string) error { - u, err := url.Parse(v) - if err != nil { - return err - } - - host := u.Hostname() - if len(host) == 0 { - return fmt.Errorf("unable to parse host from local HTTP cred provider URL") - } else if isLoopback, err := isLoopbackHost(host); err != nil { - return fmt.Errorf("failed to resolve host %q, %v", host, err) - } else if !isLoopback { - return fmt.Errorf("invalid endpoint host, %q, only host resolving to loopback addresses are allowed", host) - } - - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go deleted file mode 100644 index a8ff40d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go +++ /dev/null @@ -1,755 +0,0 @@ -package config - -import ( - "context" - "io" - "net/http" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds" - "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds" - "github.com/aws/aws-sdk-go-v2/credentials/processcreds" - "github.com/aws/aws-sdk-go-v2/credentials/ssocreds" - "github.com/aws/aws-sdk-go-v2/credentials/stscreds" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - smithybearer "github.com/aws/smithy-go/auth/bearer" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" -) - -// sharedConfigProfileProvider provides access to the shared config profile -// name external configuration value. -type sharedConfigProfileProvider interface { - getSharedConfigProfile(ctx context.Context) (string, bool, error) -} - -// getSharedConfigProfile searches the configs for a sharedConfigProfileProvider -// and returns the value if found. Returns an error if a provider fails before a -// value is found. -func getSharedConfigProfile(ctx context.Context, configs configs) (value string, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(sharedConfigProfileProvider); ok { - value, found, err = p.getSharedConfigProfile(ctx) - if err != nil || found { - break - } - } - } - return -} - -// sharedConfigFilesProvider provides access to the shared config filesnames -// external configuration value. -type sharedConfigFilesProvider interface { - getSharedConfigFiles(ctx context.Context) ([]string, bool, error) -} - -// getSharedConfigFiles searches the configs for a sharedConfigFilesProvider -// and returns the value if found. Returns an error if a provider fails before a -// value is found. -func getSharedConfigFiles(ctx context.Context, configs configs) (value []string, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(sharedConfigFilesProvider); ok { - value, found, err = p.getSharedConfigFiles(ctx) - if err != nil || found { - break - } - } - } - - return -} - -// sharedCredentialsFilesProvider provides access to the shared credentials filesnames -// external configuration value. -type sharedCredentialsFilesProvider interface { - getSharedCredentialsFiles(ctx context.Context) ([]string, bool, error) -} - -// getSharedCredentialsFiles searches the configs for a sharedCredentialsFilesProvider -// and returns the value if found. Returns an error if a provider fails before a -// value is found. -func getSharedCredentialsFiles(ctx context.Context, configs configs) (value []string, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(sharedCredentialsFilesProvider); ok { - value, found, err = p.getSharedCredentialsFiles(ctx) - if err != nil || found { - break - } - } - } - - return -} - -// customCABundleProvider provides access to the custom CA bundle PEM bytes. -type customCABundleProvider interface { - getCustomCABundle(ctx context.Context) (io.Reader, bool, error) -} - -// getCustomCABundle searches the configs for a customCABundleProvider -// and returns the value if found. Returns an error if a provider fails before a -// value is found. -func getCustomCABundle(ctx context.Context, configs configs) (value io.Reader, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(customCABundleProvider); ok { - value, found, err = p.getCustomCABundle(ctx) - if err != nil || found { - break - } - } - } - - return -} - -// regionProvider provides access to the region external configuration value. -type regionProvider interface { - getRegion(ctx context.Context) (string, bool, error) -} - -// getRegion searches the configs for a regionProvider and returns the value -// if found. Returns an error if a provider fails before a value is found. -func getRegion(ctx context.Context, configs configs) (value string, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(regionProvider); ok { - value, found, err = p.getRegion(ctx) - if err != nil || found { - break - } - } - } - return -} - -// IgnoreConfiguredEndpointsProvider is needed to search for all providers -// that provide a flag to disable configured endpoints. -type IgnoreConfiguredEndpointsProvider interface { - GetIgnoreConfiguredEndpoints(ctx context.Context) (bool, bool, error) -} - -// GetIgnoreConfiguredEndpoints is used in knowing when to disable configured -// endpoints feature. -func GetIgnoreConfiguredEndpoints(ctx context.Context, configs []interface{}) (value bool, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(IgnoreConfiguredEndpointsProvider); ok { - value, found, err = p.GetIgnoreConfiguredEndpoints(ctx) - if err != nil || found { - break - } - } - } - return -} - -type baseEndpointProvider interface { - getBaseEndpoint(ctx context.Context) (string, bool, error) -} - -func getBaseEndpoint(ctx context.Context, configs configs) (value string, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(baseEndpointProvider); ok { - value, found, err = p.getBaseEndpoint(ctx) - if err != nil || found { - break - } - } - } - return -} - -type servicesObjectProvider interface { - getServicesObject(ctx context.Context) (map[string]map[string]string, bool, error) -} - -func getServicesObject(ctx context.Context, configs configs) (value map[string]map[string]string, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(servicesObjectProvider); ok { - value, found, err = p.getServicesObject(ctx) - if err != nil || found { - break - } - } - } - return -} - -// appIDProvider provides access to the sdk app ID value -type appIDProvider interface { - getAppID(ctx context.Context) (string, bool, error) -} - -func getAppID(ctx context.Context, configs configs) (value string, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(appIDProvider); ok { - value, found, err = p.getAppID(ctx) - if err != nil || found { - break - } - } - } - return -} - -// disableRequestCompressionProvider provides access to the DisableRequestCompression -type disableRequestCompressionProvider interface { - getDisableRequestCompression(context.Context) (bool, bool, error) -} - -func getDisableRequestCompression(ctx context.Context, configs configs) (value bool, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(disableRequestCompressionProvider); ok { - value, found, err = p.getDisableRequestCompression(ctx) - if err != nil || found { - break - } - } - } - return -} - -// requestMinCompressSizeBytesProvider provides access to the MinCompressSizeBytes -type requestMinCompressSizeBytesProvider interface { - getRequestMinCompressSizeBytes(context.Context) (int64, bool, error) -} - -func getRequestMinCompressSizeBytes(ctx context.Context, configs configs) (value int64, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(requestMinCompressSizeBytesProvider); ok { - value, found, err = p.getRequestMinCompressSizeBytes(ctx) - if err != nil || found { - break - } - } - } - return -} - -// accountIDEndpointModeProvider provides access to the AccountIDEndpointMode -type accountIDEndpointModeProvider interface { - getAccountIDEndpointMode(context.Context) (aws.AccountIDEndpointMode, bool, error) -} - -func getAccountIDEndpointMode(ctx context.Context, configs configs) (value aws.AccountIDEndpointMode, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(accountIDEndpointModeProvider); ok { - value, found, err = p.getAccountIDEndpointMode(ctx) - if err != nil || found { - break - } - } - } - return -} - -// requestChecksumCalculationProvider provides access to the RequestChecksumCalculation -type requestChecksumCalculationProvider interface { - getRequestChecksumCalculation(context.Context) (aws.RequestChecksumCalculation, bool, error) -} - -func getRequestChecksumCalculation(ctx context.Context, configs configs) (value aws.RequestChecksumCalculation, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(requestChecksumCalculationProvider); ok { - value, found, err = p.getRequestChecksumCalculation(ctx) - if err != nil || found { - break - } - } - } - return -} - -// responseChecksumValidationProvider provides access to the ResponseChecksumValidation -type responseChecksumValidationProvider interface { - getResponseChecksumValidation(context.Context) (aws.ResponseChecksumValidation, bool, error) -} - -func getResponseChecksumValidation(ctx context.Context, configs configs) (value aws.ResponseChecksumValidation, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(responseChecksumValidationProvider); ok { - value, found, err = p.getResponseChecksumValidation(ctx) - if err != nil || found { - break - } - } - } - return -} - -// ec2IMDSRegionProvider provides access to the ec2 imds region -// configuration value -type ec2IMDSRegionProvider interface { - getEC2IMDSRegion(ctx context.Context) (string, bool, error) -} - -// getEC2IMDSRegion searches the configs for a ec2IMDSRegionProvider and -// returns the value if found. Returns an error if a provider fails before -// a value is found. -func getEC2IMDSRegion(ctx context.Context, configs configs) (region string, found bool, err error) { - for _, cfg := range configs { - if provider, ok := cfg.(ec2IMDSRegionProvider); ok { - region, found, err = provider.getEC2IMDSRegion(ctx) - if err != nil || found { - break - } - } - } - return -} - -// credentialsProviderProvider provides access to the credentials external -// configuration value. -type credentialsProviderProvider interface { - getCredentialsProvider(ctx context.Context) (aws.CredentialsProvider, bool, error) -} - -// getCredentialsProvider searches the configs for a credentialsProviderProvider -// and returns the value if found. Returns an error if a provider fails before a -// value is found. -func getCredentialsProvider(ctx context.Context, configs configs) (p aws.CredentialsProvider, found bool, err error) { - for _, cfg := range configs { - if provider, ok := cfg.(credentialsProviderProvider); ok { - p, found, err = provider.getCredentialsProvider(ctx) - if err != nil || found { - break - } - } - } - return -} - -// credentialsCacheOptionsProvider is an interface for retrieving a function for setting -// the aws.CredentialsCacheOptions. -type credentialsCacheOptionsProvider interface { - getCredentialsCacheOptions(ctx context.Context) (func(*aws.CredentialsCacheOptions), bool, error) -} - -// getCredentialsCacheOptionsProvider is an interface for retrieving a function for setting -// the aws.CredentialsCacheOptions. -func getCredentialsCacheOptionsProvider(ctx context.Context, configs configs) ( - f func(*aws.CredentialsCacheOptions), found bool, err error, -) { - for _, config := range configs { - if p, ok := config.(credentialsCacheOptionsProvider); ok { - f, found, err = p.getCredentialsCacheOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// bearerAuthTokenProviderProvider provides access to the bearer authentication -// token external configuration value. -type bearerAuthTokenProviderProvider interface { - getBearerAuthTokenProvider(context.Context) (smithybearer.TokenProvider, bool, error) -} - -// getBearerAuthTokenProvider searches the config sources for a -// bearerAuthTokenProviderProvider and returns the value if found. Returns an -// error if a provider fails before a value is found. -func getBearerAuthTokenProvider(ctx context.Context, configs configs) (p smithybearer.TokenProvider, found bool, err error) { - for _, cfg := range configs { - if provider, ok := cfg.(bearerAuthTokenProviderProvider); ok { - p, found, err = provider.getBearerAuthTokenProvider(ctx) - if err != nil || found { - break - } - } - } - return -} - -// bearerAuthTokenCacheOptionsProvider is an interface for retrieving a function for -// setting the smithy-go auth/bearer#TokenCacheOptions. -type bearerAuthTokenCacheOptionsProvider interface { - getBearerAuthTokenCacheOptions(context.Context) (func(*smithybearer.TokenCacheOptions), bool, error) -} - -// getBearerAuthTokenCacheOptionsProvider is an interface for retrieving a function for -// setting the smithy-go auth/bearer#TokenCacheOptions. -func getBearerAuthTokenCacheOptions(ctx context.Context, configs configs) ( - f func(*smithybearer.TokenCacheOptions), found bool, err error, -) { - for _, config := range configs { - if p, ok := config.(bearerAuthTokenCacheOptionsProvider); ok { - f, found, err = p.getBearerAuthTokenCacheOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// ssoTokenProviderOptionsProvider is an interface for retrieving a function for -// setting the SDK's credentials/ssocreds#SSOTokenProviderOptions. -type ssoTokenProviderOptionsProvider interface { - getSSOTokenProviderOptions(context.Context) (func(*ssocreds.SSOTokenProviderOptions), bool, error) -} - -// getSSOTokenProviderOptions is an interface for retrieving a function for -// setting the SDK's credentials/ssocreds#SSOTokenProviderOptions. -func getSSOTokenProviderOptions(ctx context.Context, configs configs) ( - f func(*ssocreds.SSOTokenProviderOptions), found bool, err error, -) { - for _, config := range configs { - if p, ok := config.(ssoTokenProviderOptionsProvider); ok { - f, found, err = p.getSSOTokenProviderOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// ssoTokenProviderOptionsProvider - -// processCredentialOptions is an interface for retrieving a function for setting -// the processcreds.Options. -type processCredentialOptions interface { - getProcessCredentialOptions(ctx context.Context) (func(*processcreds.Options), bool, error) -} - -// getProcessCredentialOptions searches the slice of configs and returns the first function found -func getProcessCredentialOptions(ctx context.Context, configs configs) (f func(*processcreds.Options), found bool, err error) { - for _, config := range configs { - if p, ok := config.(processCredentialOptions); ok { - f, found, err = p.getProcessCredentialOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// ec2RoleCredentialOptionsProvider is an interface for retrieving a function -// for setting the ec2rolecreds.Provider options. -type ec2RoleCredentialOptionsProvider interface { - getEC2RoleCredentialOptions(ctx context.Context) (func(*ec2rolecreds.Options), bool, error) -} - -// getEC2RoleCredentialProviderOptions searches the slice of configs and returns the first function found -func getEC2RoleCredentialProviderOptions(ctx context.Context, configs configs) (f func(*ec2rolecreds.Options), found bool, err error) { - for _, config := range configs { - if p, ok := config.(ec2RoleCredentialOptionsProvider); ok { - f, found, err = p.getEC2RoleCredentialOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// defaultRegionProvider is an interface for retrieving a default region if a region was not resolved from other sources -type defaultRegionProvider interface { - getDefaultRegion(ctx context.Context) (string, bool, error) -} - -// getDefaultRegion searches the slice of configs and returns the first fallback region found -func getDefaultRegion(ctx context.Context, configs configs) (value string, found bool, err error) { - for _, config := range configs { - if p, ok := config.(defaultRegionProvider); ok { - value, found, err = p.getDefaultRegion(ctx) - if err != nil || found { - break - } - } - } - return -} - -// endpointCredentialOptionsProvider is an interface for retrieving a function for setting -// the endpointcreds.ProviderOptions. -type endpointCredentialOptionsProvider interface { - getEndpointCredentialOptions(ctx context.Context) (func(*endpointcreds.Options), bool, error) -} - -// getEndpointCredentialProviderOptions searches the slice of configs and returns the first function found -func getEndpointCredentialProviderOptions(ctx context.Context, configs configs) (f func(*endpointcreds.Options), found bool, err error) { - for _, config := range configs { - if p, ok := config.(endpointCredentialOptionsProvider); ok { - f, found, err = p.getEndpointCredentialOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// webIdentityRoleCredentialOptionsProvider is an interface for retrieving a function for setting -// the stscreds.WebIdentityRoleProvider. -type webIdentityRoleCredentialOptionsProvider interface { - getWebIdentityRoleCredentialOptions(ctx context.Context) (func(*stscreds.WebIdentityRoleOptions), bool, error) -} - -// getWebIdentityCredentialProviderOptions searches the slice of configs and returns the first function found -func getWebIdentityCredentialProviderOptions(ctx context.Context, configs configs) (f func(*stscreds.WebIdentityRoleOptions), found bool, err error) { - for _, config := range configs { - if p, ok := config.(webIdentityRoleCredentialOptionsProvider); ok { - f, found, err = p.getWebIdentityRoleCredentialOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// assumeRoleCredentialOptionsProvider is an interface for retrieving a function for setting -// the stscreds.AssumeRoleOptions. -type assumeRoleCredentialOptionsProvider interface { - getAssumeRoleCredentialOptions(ctx context.Context) (func(*stscreds.AssumeRoleOptions), bool, error) -} - -// getAssumeRoleCredentialProviderOptions searches the slice of configs and returns the first function found -func getAssumeRoleCredentialProviderOptions(ctx context.Context, configs configs) (f func(*stscreds.AssumeRoleOptions), found bool, err error) { - for _, config := range configs { - if p, ok := config.(assumeRoleCredentialOptionsProvider); ok { - f, found, err = p.getAssumeRoleCredentialOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// HTTPClient is an HTTP client implementation -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) -} - -// httpClientProvider is an interface for retrieving HTTPClient -type httpClientProvider interface { - getHTTPClient(ctx context.Context) (HTTPClient, bool, error) -} - -// getHTTPClient searches the slice of configs and returns the HTTPClient set on configs -func getHTTPClient(ctx context.Context, configs configs) (client HTTPClient, found bool, err error) { - for _, config := range configs { - if p, ok := config.(httpClientProvider); ok { - client, found, err = p.getHTTPClient(ctx) - if err != nil || found { - break - } - } - } - return -} - -// apiOptionsProvider is an interface for retrieving APIOptions -type apiOptionsProvider interface { - getAPIOptions(ctx context.Context) ([]func(*middleware.Stack) error, bool, error) -} - -// getAPIOptions searches the slice of configs and returns the APIOptions set on configs -func getAPIOptions(ctx context.Context, configs configs) (apiOptions []func(*middleware.Stack) error, found bool, err error) { - for _, config := range configs { - if p, ok := config.(apiOptionsProvider); ok { - // retrieve APIOptions from configs and set it on cfg - apiOptions, found, err = p.getAPIOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// endpointResolverProvider is an interface for retrieving an aws.EndpointResolver from a configuration source -type endpointResolverProvider interface { - getEndpointResolver(ctx context.Context) (aws.EndpointResolver, bool, error) -} - -// getEndpointResolver searches the provided config sources for a EndpointResolverFunc that can be used -// to configure the aws.Config.EndpointResolver value. -func getEndpointResolver(ctx context.Context, configs configs) (f aws.EndpointResolver, found bool, err error) { - for _, c := range configs { - if p, ok := c.(endpointResolverProvider); ok { - f, found, err = p.getEndpointResolver(ctx) - if err != nil || found { - break - } - } - } - return -} - -// endpointResolverWithOptionsProvider is an interface for retrieving an aws.EndpointResolverWithOptions from a configuration source -type endpointResolverWithOptionsProvider interface { - getEndpointResolverWithOptions(ctx context.Context) (aws.EndpointResolverWithOptions, bool, error) -} - -// getEndpointResolver searches the provided config sources for a EndpointResolverFunc that can be used -// to configure the aws.Config.EndpointResolver value. -func getEndpointResolverWithOptions(ctx context.Context, configs configs) (f aws.EndpointResolverWithOptions, found bool, err error) { - for _, c := range configs { - if p, ok := c.(endpointResolverWithOptionsProvider); ok { - f, found, err = p.getEndpointResolverWithOptions(ctx) - if err != nil || found { - break - } - } - } - return -} - -// loggerProvider is an interface for retrieving a logging.Logger from a configuration source. -type loggerProvider interface { - getLogger(ctx context.Context) (logging.Logger, bool, error) -} - -// getLogger searches the provided config sources for a logging.Logger that can be used -// to configure the aws.Config.Logger value. -func getLogger(ctx context.Context, configs configs) (l logging.Logger, found bool, err error) { - for _, c := range configs { - if p, ok := c.(loggerProvider); ok { - l, found, err = p.getLogger(ctx) - if err != nil || found { - break - } - } - } - return -} - -// clientLogModeProvider is an interface for retrieving the aws.ClientLogMode from a configuration source. -type clientLogModeProvider interface { - getClientLogMode(ctx context.Context) (aws.ClientLogMode, bool, error) -} - -func getClientLogMode(ctx context.Context, configs configs) (m aws.ClientLogMode, found bool, err error) { - for _, c := range configs { - if p, ok := c.(clientLogModeProvider); ok { - m, found, err = p.getClientLogMode(ctx) - if err != nil || found { - break - } - } - } - return -} - -// retryProvider is an configuration provider for custom Retryer. -type retryProvider interface { - getRetryer(ctx context.Context) (func() aws.Retryer, bool, error) -} - -func getRetryer(ctx context.Context, configs configs) (v func() aws.Retryer, found bool, err error) { - for _, c := range configs { - if p, ok := c.(retryProvider); ok { - v, found, err = p.getRetryer(ctx) - if err != nil || found { - break - } - } - } - return -} - -// logConfigurationWarningsProvider is an configuration provider for -// retrieving a boolean indicating whether configuration issues should -// be logged when loading from config sources -type logConfigurationWarningsProvider interface { - getLogConfigurationWarnings(ctx context.Context) (bool, bool, error) -} - -func getLogConfigurationWarnings(ctx context.Context, configs configs) (v bool, found bool, err error) { - for _, c := range configs { - if p, ok := c.(logConfigurationWarningsProvider); ok { - v, found, err = p.getLogConfigurationWarnings(ctx) - if err != nil || found { - break - } - } - } - return -} - -// ssoCredentialOptionsProvider is an interface for retrieving a function for setting -// the ssocreds.Options. -type ssoCredentialOptionsProvider interface { - getSSOProviderOptions(context.Context) (func(*ssocreds.Options), bool, error) -} - -func getSSOProviderOptions(ctx context.Context, configs configs) (v func(options *ssocreds.Options), found bool, err error) { - for _, c := range configs { - if p, ok := c.(ssoCredentialOptionsProvider); ok { - v, found, err = p.getSSOProviderOptions(ctx) - if err != nil || found { - break - } - } - } - return v, found, err -} - -type defaultsModeIMDSClientProvider interface { - getDefaultsModeIMDSClient(context.Context) (*imds.Client, bool, error) -} - -func getDefaultsModeIMDSClient(ctx context.Context, configs configs) (v *imds.Client, found bool, err error) { - for _, c := range configs { - if p, ok := c.(defaultsModeIMDSClientProvider); ok { - v, found, err = p.getDefaultsModeIMDSClient(ctx) - if err != nil || found { - break - } - } - } - return v, found, err -} - -type defaultsModeProvider interface { - getDefaultsMode(context.Context) (aws.DefaultsMode, bool, error) -} - -func getDefaultsMode(ctx context.Context, configs configs) (v aws.DefaultsMode, found bool, err error) { - for _, c := range configs { - if p, ok := c.(defaultsModeProvider); ok { - v, found, err = p.getDefaultsMode(ctx) - if err != nil || found { - break - } - } - } - return v, found, err -} - -type retryMaxAttemptsProvider interface { - GetRetryMaxAttempts(context.Context) (int, bool, error) -} - -func getRetryMaxAttempts(ctx context.Context, configs configs) (v int, found bool, err error) { - for _, c := range configs { - if p, ok := c.(retryMaxAttemptsProvider); ok { - v, found, err = p.GetRetryMaxAttempts(ctx) - if err != nil || found { - break - } - } - } - return v, found, err -} - -type retryModeProvider interface { - GetRetryMode(context.Context) (aws.RetryMode, bool, error) -} - -func getRetryMode(ctx context.Context, configs configs) (v aws.RetryMode, found bool, err error) { - for _, c := range configs { - if p, ok := c.(retryModeProvider); ok { - v, found, err = p.GetRetryMode(ctx) - if err != nil || found { - break - } - } - } - return v, found, err -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go deleted file mode 100644 index a68bd09..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go +++ /dev/null @@ -1,413 +0,0 @@ -package config - -import ( - "context" - "crypto/tls" - "crypto/x509" - "fmt" - "io/ioutil" - "net/http" - "os" - - "github.com/aws/aws-sdk-go-v2/aws" - awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - "github.com/aws/smithy-go/logging" -) - -// resolveDefaultAWSConfig will write default configuration values into the cfg -// value. It will write the default values, overwriting any previous value. -// -// This should be used as the first resolver in the slice of resolvers when -// resolving external configuration. -func resolveDefaultAWSConfig(ctx context.Context, cfg *aws.Config, cfgs configs) error { - var sources []interface{} - for _, s := range cfgs { - sources = append(sources, s) - } - - *cfg = aws.Config{ - Logger: logging.NewStandardLogger(os.Stderr), - ConfigSources: sources, - } - return nil -} - -// resolveCustomCABundle extracts the first instance of a custom CA bundle filename -// from the external configurations. It will update the HTTP Client's builder -// to be configured with the custom CA bundle. -// -// Config provider used: -// * customCABundleProvider -func resolveCustomCABundle(ctx context.Context, cfg *aws.Config, cfgs configs) error { - pemCerts, found, err := getCustomCABundle(ctx, cfgs) - if err != nil { - // TODO error handling, What is the best way to handle this? - // capture previous errors continue. error out if all errors - return err - } - if !found { - return nil - } - - if cfg.HTTPClient == nil { - cfg.HTTPClient = awshttp.NewBuildableClient() - } - - trOpts, ok := cfg.HTTPClient.(*awshttp.BuildableClient) - if !ok { - return fmt.Errorf("unable to add custom RootCAs HTTPClient, "+ - "has no WithTransportOptions, %T", cfg.HTTPClient) - } - - var appendErr error - client := trOpts.WithTransportOptions(func(tr *http.Transport) { - if tr.TLSClientConfig == nil { - tr.TLSClientConfig = &tls.Config{} - } - if tr.TLSClientConfig.RootCAs == nil { - tr.TLSClientConfig.RootCAs = x509.NewCertPool() - } - - b, err := ioutil.ReadAll(pemCerts) - if err != nil { - appendErr = fmt.Errorf("failed to read custom CA bundle PEM file") - } - - if !tr.TLSClientConfig.RootCAs.AppendCertsFromPEM(b) { - appendErr = fmt.Errorf("failed to load custom CA bundle PEM file") - } - }) - if appendErr != nil { - return appendErr - } - - cfg.HTTPClient = client - return err -} - -// resolveRegion extracts the first instance of a Region from the configs slice. -// -// Config providers used: -// * regionProvider -func resolveRegion(ctx context.Context, cfg *aws.Config, configs configs) error { - v, found, err := getRegion(ctx, configs) - if err != nil { - // TODO error handling, What is the best way to handle this? - // capture previous errors continue. error out if all errors - return err - } - if !found { - return nil - } - - cfg.Region = v - return nil -} - -func resolveBaseEndpoint(ctx context.Context, cfg *aws.Config, configs configs) error { - var downcastCfgSources []interface{} - for _, cs := range configs { - downcastCfgSources = append(downcastCfgSources, interface{}(cs)) - } - - if val, found, err := GetIgnoreConfiguredEndpoints(ctx, downcastCfgSources); found && val && err == nil { - cfg.BaseEndpoint = nil - return nil - } - - v, found, err := getBaseEndpoint(ctx, configs) - if err != nil { - return err - } - - if !found { - return nil - } - cfg.BaseEndpoint = aws.String(v) - return nil -} - -// resolveAppID extracts the sdk app ID from the configs slice's SharedConfig or env var -func resolveAppID(ctx context.Context, cfg *aws.Config, configs configs) error { - ID, _, err := getAppID(ctx, configs) - if err != nil { - return err - } - - cfg.AppID = ID - return nil -} - -// resolveDisableRequestCompression extracts the DisableRequestCompression from the configs slice's -// SharedConfig or EnvConfig -func resolveDisableRequestCompression(ctx context.Context, cfg *aws.Config, configs configs) error { - disable, _, err := getDisableRequestCompression(ctx, configs) - if err != nil { - return err - } - - cfg.DisableRequestCompression = disable - return nil -} - -// resolveRequestMinCompressSizeBytes extracts the RequestMinCompressSizeBytes from the configs slice's -// SharedConfig or EnvConfig -func resolveRequestMinCompressSizeBytes(ctx context.Context, cfg *aws.Config, configs configs) error { - minBytes, found, err := getRequestMinCompressSizeBytes(ctx, configs) - if err != nil { - return err - } - // must set a default min size 10240 if not configured - if !found { - minBytes = 10240 - } - cfg.RequestMinCompressSizeBytes = minBytes - return nil -} - -// resolveAccountIDEndpointMode extracts the AccountIDEndpointMode from the configs slice's -// SharedConfig or EnvConfig -func resolveAccountIDEndpointMode(ctx context.Context, cfg *aws.Config, configs configs) error { - m, found, err := getAccountIDEndpointMode(ctx, configs) - if err != nil { - return err - } - - if !found { - m = aws.AccountIDEndpointModePreferred - } - - cfg.AccountIDEndpointMode = m - return nil -} - -// resolveRequestChecksumCalculation extracts the RequestChecksumCalculation from the configs slice's -// SharedConfig or EnvConfig -func resolveRequestChecksumCalculation(ctx context.Context, cfg *aws.Config, configs configs) error { - c, found, err := getRequestChecksumCalculation(ctx, configs) - if err != nil { - return err - } - - if !found { - c = aws.RequestChecksumCalculationWhenSupported - } - cfg.RequestChecksumCalculation = c - return nil -} - -// resolveResponseValidation extracts the ResponseChecksumValidation from the configs slice's -// SharedConfig or EnvConfig -func resolveResponseChecksumValidation(ctx context.Context, cfg *aws.Config, configs configs) error { - c, found, err := getResponseChecksumValidation(ctx, configs) - if err != nil { - return err - } - - if !found { - c = aws.ResponseChecksumValidationWhenSupported - } - cfg.ResponseChecksumValidation = c - return nil -} - -// resolveDefaultRegion extracts the first instance of a default region and sets `aws.Config.Region` to the default -// region if region had not been resolved from other sources. -func resolveDefaultRegion(ctx context.Context, cfg *aws.Config, configs configs) error { - if len(cfg.Region) > 0 { - return nil - } - - v, found, err := getDefaultRegion(ctx, configs) - if err != nil { - return err - } - if !found { - return nil - } - - cfg.Region = v - - return nil -} - -// resolveHTTPClient extracts the first instance of a HTTPClient and sets `aws.Config.HTTPClient` to the HTTPClient instance -// if one has not been resolved from other sources. -func resolveHTTPClient(ctx context.Context, cfg *aws.Config, configs configs) error { - c, found, err := getHTTPClient(ctx, configs) - if err != nil { - return err - } - if !found { - return nil - } - - cfg.HTTPClient = c - return nil -} - -// resolveAPIOptions extracts the first instance of APIOptions and sets `aws.Config.APIOptions` to the resolved API options -// if one has not been resolved from other sources. -func resolveAPIOptions(ctx context.Context, cfg *aws.Config, configs configs) error { - o, found, err := getAPIOptions(ctx, configs) - if err != nil { - return err - } - if !found { - return nil - } - - cfg.APIOptions = o - - return nil -} - -// resolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice -// and sets the functions result on the aws.Config.EndpointResolver -func resolveEndpointResolver(ctx context.Context, cfg *aws.Config, configs configs) error { - endpointResolver, found, err := getEndpointResolver(ctx, configs) - if err != nil { - return err - } - if !found { - return nil - } - - cfg.EndpointResolver = endpointResolver - - return nil -} - -// resolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice -// and sets the functions result on the aws.Config.EndpointResolver -func resolveEndpointResolverWithOptions(ctx context.Context, cfg *aws.Config, configs configs) error { - endpointResolver, found, err := getEndpointResolverWithOptions(ctx, configs) - if err != nil { - return err - } - if !found { - return nil - } - - cfg.EndpointResolverWithOptions = endpointResolver - - return nil -} - -func resolveLogger(ctx context.Context, cfg *aws.Config, configs configs) error { - logger, found, err := getLogger(ctx, configs) - if err != nil { - return err - } - if !found { - return nil - } - - cfg.Logger = logger - - return nil -} - -func resolveClientLogMode(ctx context.Context, cfg *aws.Config, configs configs) error { - mode, found, err := getClientLogMode(ctx, configs) - if err != nil { - return err - } - if !found { - return nil - } - - cfg.ClientLogMode = mode - - return nil -} - -func resolveRetryer(ctx context.Context, cfg *aws.Config, configs configs) error { - retryer, found, err := getRetryer(ctx, configs) - if err != nil { - return err - } - - if found { - cfg.Retryer = retryer - return nil - } - - // Only load the retry options if a custom retryer has not be specified. - if err = resolveRetryMaxAttempts(ctx, cfg, configs); err != nil { - return err - } - return resolveRetryMode(ctx, cfg, configs) -} - -func resolveEC2IMDSRegion(ctx context.Context, cfg *aws.Config, configs configs) error { - if len(cfg.Region) > 0 { - return nil - } - - region, found, err := getEC2IMDSRegion(ctx, configs) - if err != nil { - return err - } - if !found { - return nil - } - - cfg.Region = region - - return nil -} - -func resolveDefaultsModeOptions(ctx context.Context, cfg *aws.Config, configs configs) error { - defaultsMode, found, err := getDefaultsMode(ctx, configs) - if err != nil { - return err - } - if !found { - defaultsMode = aws.DefaultsModeLegacy - } - - var environment aws.RuntimeEnvironment - if defaultsMode == aws.DefaultsModeAuto { - envConfig, _, _ := getAWSConfigSources(configs) - - client, found, err := getDefaultsModeIMDSClient(ctx, configs) - if err != nil { - return err - } - if !found { - client = imds.NewFromConfig(*cfg) - } - - environment, err = resolveDefaultsModeRuntimeEnvironment(ctx, envConfig, client) - if err != nil { - return err - } - } - - cfg.DefaultsMode = defaultsMode - cfg.RuntimeEnvironment = environment - - return nil -} - -func resolveRetryMaxAttempts(ctx context.Context, cfg *aws.Config, configs configs) error { - maxAttempts, found, err := getRetryMaxAttempts(ctx, configs) - if err != nil || !found { - return err - } - cfg.RetryMaxAttempts = maxAttempts - - return nil -} - -func resolveRetryMode(ctx context.Context, cfg *aws.Config, configs configs) error { - retryMode, found, err := getRetryMode(ctx, configs) - if err != nil || !found { - return err - } - cfg.RetryMode = retryMode - - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_bearer_token.go b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_bearer_token.go deleted file mode 100644 index a8ebb3c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_bearer_token.go +++ /dev/null @@ -1,122 +0,0 @@ -package config - -import ( - "context" - "fmt" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/credentials/ssocreds" - "github.com/aws/aws-sdk-go-v2/service/ssooidc" - smithybearer "github.com/aws/smithy-go/auth/bearer" -) - -// resolveBearerAuthToken extracts a token provider from the config sources. -// -// If an explicit bearer authentication token provider is not found the -// resolver will fallback to resolving token provider via other config sources -// such as SharedConfig. -func resolveBearerAuthToken(ctx context.Context, cfg *aws.Config, configs configs) error { - found, err := resolveBearerAuthTokenProvider(ctx, cfg, configs) - if found || err != nil { - return err - } - - return resolveBearerAuthTokenProviderChain(ctx, cfg, configs) -} - -// resolveBearerAuthTokenProvider extracts the first instance of -// BearerAuthTokenProvider from the config sources. -// -// The resolved BearerAuthTokenProvider will be wrapped in a cache to ensure -// the Token is only refreshed when needed. This also protects the -// TokenProvider so it can be used concurrently. -// -// Config providers used: -// * bearerAuthTokenProviderProvider -func resolveBearerAuthTokenProvider(ctx context.Context, cfg *aws.Config, configs configs) (bool, error) { - tokenProvider, found, err := getBearerAuthTokenProvider(ctx, configs) - if !found || err != nil { - return false, err - } - - cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache( - ctx, configs, tokenProvider) - if err != nil { - return false, err - } - - return true, nil -} - -func resolveBearerAuthTokenProviderChain(ctx context.Context, cfg *aws.Config, configs configs) (err error) { - _, sharedConfig, _ := getAWSConfigSources(configs) - - var provider smithybearer.TokenProvider - - if sharedConfig.SSOSession != nil { - provider, err = resolveBearerAuthSSOTokenProvider( - ctx, cfg, sharedConfig.SSOSession, configs) - } - - if err == nil && provider != nil { - cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache( - ctx, configs, provider) - } - - return err -} - -func resolveBearerAuthSSOTokenProvider(ctx context.Context, cfg *aws.Config, session *SSOSession, configs configs) (*ssocreds.SSOTokenProvider, error) { - ssoTokenProviderOptionsFn, found, err := getSSOTokenProviderOptions(ctx, configs) - if err != nil { - return nil, fmt.Errorf("failed to get SSOTokenProviderOptions from config sources, %w", err) - } - - var optFns []func(*ssocreds.SSOTokenProviderOptions) - if found { - optFns = append(optFns, ssoTokenProviderOptionsFn) - } - - cachePath, err := ssocreds.StandardCachedTokenFilepath(session.Name) - if err != nil { - return nil, fmt.Errorf("failed to get SSOTokenProvider's cache path, %w", err) - } - - client := ssooidc.NewFromConfig(*cfg) - provider := ssocreds.NewSSOTokenProvider(client, cachePath, optFns...) - - return provider, nil -} - -// wrapWithBearerAuthTokenCache will wrap provider with an smithy-go -// bearer/auth#TokenCache with the provided options if the provider is not -// already a TokenCache. -func wrapWithBearerAuthTokenCache( - ctx context.Context, - cfgs configs, - provider smithybearer.TokenProvider, - optFns ...func(*smithybearer.TokenCacheOptions), -) (smithybearer.TokenProvider, error) { - _, ok := provider.(*smithybearer.TokenCache) - if ok { - return provider, nil - } - - tokenCacheConfigOptions, optionsFound, err := getBearerAuthTokenCacheOptions(ctx, cfgs) - if err != nil { - return nil, err - } - - opts := make([]func(*smithybearer.TokenCacheOptions), 0, 2+len(optFns)) - opts = append(opts, func(o *smithybearer.TokenCacheOptions) { - o.RefreshBeforeExpires = 5 * time.Minute - o.RetrieveBearerTokenTimeout = 30 * time.Second - }) - opts = append(opts, optFns...) - if optionsFound { - opts = append(opts, tokenCacheConfigOptions) - } - - return smithybearer.NewTokenCache(provider, opts...), nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_credentials.go b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_credentials.go deleted file mode 100644 index 7ae252e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_credentials.go +++ /dev/null @@ -1,569 +0,0 @@ -package config - -import ( - "context" - "fmt" - "io/ioutil" - "net" - "net/url" - "os" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/credentials" - "github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds" - "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds" - "github.com/aws/aws-sdk-go-v2/credentials/processcreds" - "github.com/aws/aws-sdk-go-v2/credentials/ssocreds" - "github.com/aws/aws-sdk-go-v2/credentials/stscreds" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - "github.com/aws/aws-sdk-go-v2/service/sso" - "github.com/aws/aws-sdk-go-v2/service/ssooidc" - "github.com/aws/aws-sdk-go-v2/service/sts" -) - -const ( - // valid credential source values - credSourceEc2Metadata = "Ec2InstanceMetadata" - credSourceEnvironment = "Environment" - credSourceECSContainer = "EcsContainer" - httpProviderAuthFileEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE" -) - -// direct representation of the IPv4 address for the ECS container -// "169.254.170.2" -var ecsContainerIPv4 net.IP = []byte{ - 169, 254, 170, 2, -} - -// direct representation of the IPv4 address for the EKS container -// "169.254.170.23" -var eksContainerIPv4 net.IP = []byte{ - 169, 254, 170, 23, -} - -// direct representation of the IPv6 address for the EKS container -// "fd00:ec2::23" -var eksContainerIPv6 net.IP = []byte{ - 0xFD, 0, 0xE, 0xC2, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0x23, -} - -var ( - ecsContainerEndpoint = "http://169.254.170.2" // not constant to allow for swapping during unit-testing -) - -// resolveCredentials extracts a credential provider from slice of config -// sources. -// -// If an explicit credential provider is not found the resolver will fallback -// to resolving credentials by extracting a credential provider from EnvConfig -// and SharedConfig. -func resolveCredentials(ctx context.Context, cfg *aws.Config, configs configs) error { - found, err := resolveCredentialProvider(ctx, cfg, configs) - if found || err != nil { - return err - } - - return resolveCredentialChain(ctx, cfg, configs) -} - -// resolveCredentialProvider extracts the first instance of Credentials from the -// config slices. -// -// The resolved CredentialProvider will be wrapped in a cache to ensure the -// credentials are only refreshed when needed. This also protects the -// credential provider to be used concurrently. -// -// Config providers used: -// * credentialsProviderProvider -func resolveCredentialProvider(ctx context.Context, cfg *aws.Config, configs configs) (bool, error) { - credProvider, found, err := getCredentialsProvider(ctx, configs) - if !found || err != nil { - return false, err - } - - cfg.Credentials, err = wrapWithCredentialsCache(ctx, configs, credProvider) - if err != nil { - return false, err - } - - return true, nil -} - -// resolveCredentialChain resolves a credential provider chain using EnvConfig -// and SharedConfig if present in the slice of provided configs. -// -// The resolved CredentialProvider will be wrapped in a cache to ensure the -// credentials are only refreshed when needed. This also protects the -// credential provider to be used concurrently. -func resolveCredentialChain(ctx context.Context, cfg *aws.Config, configs configs) (err error) { - envConfig, sharedConfig, other := getAWSConfigSources(configs) - - // When checking if a profile was specified programmatically we should only consider the "other" - // configuration sources that have been provided. This ensures we correctly honor the expected credential - // hierarchy. - _, sharedProfileSet, err := getSharedConfigProfile(ctx, other) - if err != nil { - return err - } - - switch { - case sharedProfileSet: - err = resolveCredsFromProfile(ctx, cfg, envConfig, sharedConfig, other) - case envConfig.Credentials.HasKeys(): - cfg.Credentials = credentials.StaticCredentialsProvider{Value: envConfig.Credentials} - case len(envConfig.WebIdentityTokenFilePath) > 0: - err = assumeWebIdentity(ctx, cfg, envConfig.WebIdentityTokenFilePath, envConfig.RoleARN, envConfig.RoleSessionName, configs) - default: - err = resolveCredsFromProfile(ctx, cfg, envConfig, sharedConfig, other) - } - if err != nil { - return err - } - - // Wrap the resolved provider in a cache so the SDK will cache credentials. - cfg.Credentials, err = wrapWithCredentialsCache(ctx, configs, cfg.Credentials) - if err != nil { - return err - } - - return nil -} - -func resolveCredsFromProfile(ctx context.Context, cfg *aws.Config, envConfig *EnvConfig, sharedConfig *SharedConfig, configs configs) (err error) { - - switch { - case sharedConfig.Source != nil: - // Assume IAM role with credentials source from a different profile. - err = resolveCredsFromProfile(ctx, cfg, envConfig, sharedConfig.Source, configs) - - case sharedConfig.Credentials.HasKeys(): - // Static Credentials from Shared Config/Credentials file. - cfg.Credentials = credentials.StaticCredentialsProvider{ - Value: sharedConfig.Credentials, - } - - case len(sharedConfig.CredentialSource) != 0: - err = resolveCredsFromSource(ctx, cfg, envConfig, sharedConfig, configs) - - case len(sharedConfig.WebIdentityTokenFile) != 0: - // Credentials from Assume Web Identity token require an IAM Role, and - // that roll will be assumed. May be wrapped with another assume role - // via SourceProfile. - return assumeWebIdentity(ctx, cfg, sharedConfig.WebIdentityTokenFile, sharedConfig.RoleARN, sharedConfig.RoleSessionName, configs) - - case sharedConfig.hasSSOConfiguration(): - err = resolveSSOCredentials(ctx, cfg, sharedConfig, configs) - - case len(sharedConfig.CredentialProcess) != 0: - // Get credentials from CredentialProcess - err = processCredentials(ctx, cfg, sharedConfig, configs) - - case len(envConfig.ContainerCredentialsRelativePath) != 0: - err = resolveHTTPCredProvider(ctx, cfg, ecsContainerURI(envConfig.ContainerCredentialsRelativePath), envConfig.ContainerAuthorizationToken, configs) - - case len(envConfig.ContainerCredentialsEndpoint) != 0: - err = resolveLocalHTTPCredProvider(ctx, cfg, envConfig.ContainerCredentialsEndpoint, envConfig.ContainerAuthorizationToken, configs) - - default: - err = resolveEC2RoleCredentials(ctx, cfg, configs) - } - if err != nil { - return err - } - - if len(sharedConfig.RoleARN) > 0 { - return credsFromAssumeRole(ctx, cfg, sharedConfig, configs) - } - - return nil -} - -func resolveSSOCredentials(ctx context.Context, cfg *aws.Config, sharedConfig *SharedConfig, configs configs) error { - if err := sharedConfig.validateSSOConfiguration(); err != nil { - return err - } - - var options []func(*ssocreds.Options) - v, found, err := getSSOProviderOptions(ctx, configs) - if err != nil { - return err - } - if found { - options = append(options, v) - } - - cfgCopy := cfg.Copy() - - if sharedConfig.SSOSession != nil { - ssoTokenProviderOptionsFn, found, err := getSSOTokenProviderOptions(ctx, configs) - if err != nil { - return fmt.Errorf("failed to get SSOTokenProviderOptions from config sources, %w", err) - } - var optFns []func(*ssocreds.SSOTokenProviderOptions) - if found { - optFns = append(optFns, ssoTokenProviderOptionsFn) - } - cfgCopy.Region = sharedConfig.SSOSession.SSORegion - cachedPath, err := ssocreds.StandardCachedTokenFilepath(sharedConfig.SSOSession.Name) - if err != nil { - return err - } - oidcClient := ssooidc.NewFromConfig(cfgCopy) - tokenProvider := ssocreds.NewSSOTokenProvider(oidcClient, cachedPath, optFns...) - options = append(options, func(o *ssocreds.Options) { - o.SSOTokenProvider = tokenProvider - o.CachedTokenFilepath = cachedPath - }) - } else { - cfgCopy.Region = sharedConfig.SSORegion - } - - cfg.Credentials = ssocreds.New(sso.NewFromConfig(cfgCopy), sharedConfig.SSOAccountID, sharedConfig.SSORoleName, sharedConfig.SSOStartURL, options...) - - return nil -} - -func ecsContainerURI(path string) string { - return fmt.Sprintf("%s%s", ecsContainerEndpoint, path) -} - -func processCredentials(ctx context.Context, cfg *aws.Config, sharedConfig *SharedConfig, configs configs) error { - var opts []func(*processcreds.Options) - - options, found, err := getProcessCredentialOptions(ctx, configs) - if err != nil { - return err - } - if found { - opts = append(opts, options) - } - - cfg.Credentials = processcreds.NewProvider(sharedConfig.CredentialProcess, opts...) - - return nil -} - -// isAllowedHost allows host to be loopback or known ECS/EKS container IPs -// -// host can either be an IP address OR an unresolved hostname - resolution will -// be automatically performed in the latter case -func isAllowedHost(host string) (bool, error) { - if ip := net.ParseIP(host); ip != nil { - return isIPAllowed(ip), nil - } - - addrs, err := lookupHostFn(host) - if err != nil { - return false, err - } - - for _, addr := range addrs { - if ip := net.ParseIP(addr); ip == nil || !isIPAllowed(ip) { - return false, nil - } - } - - return true, nil -} - -func isIPAllowed(ip net.IP) bool { - return ip.IsLoopback() || - ip.Equal(ecsContainerIPv4) || - ip.Equal(eksContainerIPv4) || - ip.Equal(eksContainerIPv6) -} - -func resolveLocalHTTPCredProvider(ctx context.Context, cfg *aws.Config, endpointURL, authToken string, configs configs) error { - var resolveErr error - - parsed, err := url.Parse(endpointURL) - if err != nil { - resolveErr = fmt.Errorf("invalid URL, %w", err) - } else { - host := parsed.Hostname() - if len(host) == 0 { - resolveErr = fmt.Errorf("unable to parse host from local HTTP cred provider URL") - } else if parsed.Scheme == "http" { - if isAllowedHost, allowHostErr := isAllowedHost(host); allowHostErr != nil { - resolveErr = fmt.Errorf("failed to resolve host %q, %v", host, allowHostErr) - } else if !isAllowedHost { - resolveErr = fmt.Errorf("invalid endpoint host, %q, only loopback/ecs/eks hosts are allowed", host) - } - } - } - - if resolveErr != nil { - return resolveErr - } - - return resolveHTTPCredProvider(ctx, cfg, endpointURL, authToken, configs) -} - -func resolveHTTPCredProvider(ctx context.Context, cfg *aws.Config, url, authToken string, configs configs) error { - optFns := []func(*endpointcreds.Options){ - func(options *endpointcreds.Options) { - if len(authToken) != 0 { - options.AuthorizationToken = authToken - } - if authFilePath := os.Getenv(httpProviderAuthFileEnvVar); authFilePath != "" { - options.AuthorizationTokenProvider = endpointcreds.TokenProviderFunc(func() (string, error) { - var contents []byte - var err error - if contents, err = ioutil.ReadFile(authFilePath); err != nil { - return "", fmt.Errorf("failed to read authorization token from %v: %v", authFilePath, err) - } - return string(contents), nil - }) - } - options.APIOptions = cfg.APIOptions - if cfg.Retryer != nil { - options.Retryer = cfg.Retryer() - } - }, - } - - optFn, found, err := getEndpointCredentialProviderOptions(ctx, configs) - if err != nil { - return err - } - if found { - optFns = append(optFns, optFn) - } - - provider := endpointcreds.New(url, optFns...) - - cfg.Credentials, err = wrapWithCredentialsCache(ctx, configs, provider, func(options *aws.CredentialsCacheOptions) { - options.ExpiryWindow = 5 * time.Minute - }) - if err != nil { - return err - } - - return nil -} - -func resolveCredsFromSource(ctx context.Context, cfg *aws.Config, envConfig *EnvConfig, sharedCfg *SharedConfig, configs configs) (err error) { - switch sharedCfg.CredentialSource { - case credSourceEc2Metadata: - return resolveEC2RoleCredentials(ctx, cfg, configs) - - case credSourceEnvironment: - cfg.Credentials = credentials.StaticCredentialsProvider{Value: envConfig.Credentials} - - case credSourceECSContainer: - if len(envConfig.ContainerCredentialsRelativePath) != 0 { - return resolveHTTPCredProvider(ctx, cfg, ecsContainerURI(envConfig.ContainerCredentialsRelativePath), envConfig.ContainerAuthorizationToken, configs) - } - if len(envConfig.ContainerCredentialsEndpoint) != 0 { - return resolveLocalHTTPCredProvider(ctx, cfg, envConfig.ContainerCredentialsEndpoint, envConfig.ContainerAuthorizationToken, configs) - } - return fmt.Errorf("EcsContainer was specified as the credential_source, but neither 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' or AWS_CONTAINER_CREDENTIALS_FULL_URI' was set") - - default: - return fmt.Errorf("credential_source values must be EcsContainer, Ec2InstanceMetadata, or Environment") - } - - return nil -} - -func resolveEC2RoleCredentials(ctx context.Context, cfg *aws.Config, configs configs) error { - optFns := make([]func(*ec2rolecreds.Options), 0, 2) - - optFn, found, err := getEC2RoleCredentialProviderOptions(ctx, configs) - if err != nil { - return err - } - if found { - optFns = append(optFns, optFn) - } - - optFns = append(optFns, func(o *ec2rolecreds.Options) { - // Only define a client from config if not already defined. - if o.Client == nil { - o.Client = imds.NewFromConfig(*cfg) - } - }) - - provider := ec2rolecreds.New(optFns...) - - cfg.Credentials, err = wrapWithCredentialsCache(ctx, configs, provider) - if err != nil { - return err - } - - return nil -} - -func getAWSConfigSources(cfgs configs) (*EnvConfig, *SharedConfig, configs) { - var ( - envConfig *EnvConfig - sharedConfig *SharedConfig - other configs - ) - - for i := range cfgs { - switch c := cfgs[i].(type) { - case EnvConfig: - if envConfig == nil { - envConfig = &c - } - case *EnvConfig: - if envConfig == nil { - envConfig = c - } - case SharedConfig: - if sharedConfig == nil { - sharedConfig = &c - } - case *SharedConfig: - if envConfig == nil { - sharedConfig = c - } - default: - other = append(other, c) - } - } - - if envConfig == nil { - envConfig = &EnvConfig{} - } - - if sharedConfig == nil { - sharedConfig = &SharedConfig{} - } - - return envConfig, sharedConfig, other -} - -// AssumeRoleTokenProviderNotSetError is an error returned when creating a -// session when the MFAToken option is not set when shared config is configured -// load assume a role with an MFA token. -type AssumeRoleTokenProviderNotSetError struct{} - -// Error is the error message -func (e AssumeRoleTokenProviderNotSetError) Error() string { - return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.") -} - -func assumeWebIdentity(ctx context.Context, cfg *aws.Config, filepath string, roleARN, sessionName string, configs configs) error { - if len(filepath) == 0 { - return fmt.Errorf("token file path is not set") - } - - optFns := []func(*stscreds.WebIdentityRoleOptions){ - func(options *stscreds.WebIdentityRoleOptions) { - options.RoleSessionName = sessionName - }, - } - - optFn, found, err := getWebIdentityCredentialProviderOptions(ctx, configs) - if err != nil { - return err - } - - if found { - optFns = append(optFns, optFn) - } - - opts := stscreds.WebIdentityRoleOptions{ - RoleARN: roleARN, - } - - for _, fn := range optFns { - fn(&opts) - } - - if len(opts.RoleARN) == 0 { - return fmt.Errorf("role ARN is not set") - } - - client := opts.Client - if client == nil { - client = sts.NewFromConfig(*cfg) - } - - provider := stscreds.NewWebIdentityRoleProvider(client, roleARN, stscreds.IdentityTokenFile(filepath), optFns...) - - cfg.Credentials = provider - - return nil -} - -func credsFromAssumeRole(ctx context.Context, cfg *aws.Config, sharedCfg *SharedConfig, configs configs) (err error) { - optFns := []func(*stscreds.AssumeRoleOptions){ - func(options *stscreds.AssumeRoleOptions) { - options.RoleSessionName = sharedCfg.RoleSessionName - if sharedCfg.RoleDurationSeconds != nil { - if *sharedCfg.RoleDurationSeconds/time.Minute > 15 { - options.Duration = *sharedCfg.RoleDurationSeconds - } - } - // Assume role with external ID - if len(sharedCfg.ExternalID) > 0 { - options.ExternalID = aws.String(sharedCfg.ExternalID) - } - - // Assume role with MFA - if len(sharedCfg.MFASerial) != 0 { - options.SerialNumber = aws.String(sharedCfg.MFASerial) - } - }, - } - - optFn, found, err := getAssumeRoleCredentialProviderOptions(ctx, configs) - if err != nil { - return err - } - if found { - optFns = append(optFns, optFn) - } - - { - // Synthesize options early to validate configuration errors sooner to ensure a token provider - // is present if the SerialNumber was set. - var o stscreds.AssumeRoleOptions - for _, fn := range optFns { - fn(&o) - } - if o.TokenProvider == nil && o.SerialNumber != nil { - return AssumeRoleTokenProviderNotSetError{} - } - } - - cfg.Credentials = stscreds.NewAssumeRoleProvider(sts.NewFromConfig(*cfg), sharedCfg.RoleARN, optFns...) - - return nil -} - -// wrapWithCredentialsCache will wrap provider with an aws.CredentialsCache -// with the provided options if the provider is not already a -// aws.CredentialsCache. -func wrapWithCredentialsCache( - ctx context.Context, - cfgs configs, - provider aws.CredentialsProvider, - optFns ...func(options *aws.CredentialsCacheOptions), -) (aws.CredentialsProvider, error) { - _, ok := provider.(*aws.CredentialsCache) - if ok { - return provider, nil - } - - credCacheOptions, optionsFound, err := getCredentialsCacheOptionsProvider(ctx, cfgs) - if err != nil { - return nil, err - } - - // force allocation of a new slice if the additional options are - // needed, to prevent overwriting the passed in slice of options. - optFns = optFns[:len(optFns):len(optFns)] - if optionsFound { - optFns = append(optFns, credCacheOptions) - } - - return aws.NewCredentialsCache(provider, optFns...), nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go b/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go deleted file mode 100644 index 00b071f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go +++ /dev/null @@ -1,1680 +0,0 @@ -package config - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - "github.com/aws/aws-sdk-go-v2/internal/ini" - "github.com/aws/aws-sdk-go-v2/internal/shareddefaults" - "github.com/aws/smithy-go/logging" - smithyrequestcompression "github.com/aws/smithy-go/private/requestcompression" -) - -const ( - // Prefix to use for filtering profiles. The profile prefix should only - // exist in the shared config file, not the credentials file. - profilePrefix = `profile ` - - // Prefix to be used for SSO sections. These are supposed to only exist in - // the shared config file, not the credentials file. - ssoSectionPrefix = `sso-session ` - - // Prefix for services section. It is referenced in profile via the services - // parameter to configure clients for service-specific parameters. - servicesPrefix = `services ` - - // string equivalent for boolean - endpointDiscoveryDisabled = `false` - endpointDiscoveryEnabled = `true` - endpointDiscoveryAuto = `auto` - - // Static Credentials group - accessKeyIDKey = `aws_access_key_id` // group required - secretAccessKey = `aws_secret_access_key` // group required - sessionTokenKey = `aws_session_token` // optional - - // Assume Role Credentials group - roleArnKey = `role_arn` // group required - sourceProfileKey = `source_profile` // group required - credentialSourceKey = `credential_source` // group required (or source_profile) - externalIDKey = `external_id` // optional - mfaSerialKey = `mfa_serial` // optional - roleSessionNameKey = `role_session_name` // optional - roleDurationSecondsKey = "duration_seconds" // optional - - // AWS Single Sign-On (AWS SSO) group - ssoSessionNameKey = "sso_session" - - ssoRegionKey = "sso_region" - ssoStartURLKey = "sso_start_url" - - ssoAccountIDKey = "sso_account_id" - ssoRoleNameKey = "sso_role_name" - - // Additional Config fields - regionKey = `region` - - // endpoint discovery group - enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional - - // External Credential process - credentialProcessKey = `credential_process` // optional - - // Web Identity Token File - webIdentityTokenFileKey = `web_identity_token_file` // optional - - // S3 ARN Region Usage - s3UseARNRegionKey = "s3_use_arn_region" - - ec2MetadataServiceEndpointModeKey = "ec2_metadata_service_endpoint_mode" - - ec2MetadataServiceEndpointKey = "ec2_metadata_service_endpoint" - - ec2MetadataV1DisabledKey = "ec2_metadata_v1_disabled" - - // Use DualStack Endpoint Resolution - useDualStackEndpoint = "use_dualstack_endpoint" - - // DefaultSharedConfigProfile is the default profile to be used when - // loading configuration from the config files if another profile name - // is not provided. - DefaultSharedConfigProfile = `default` - - // S3 Disable Multi-Region AccessPoints - s3DisableMultiRegionAccessPointsKey = `s3_disable_multiregion_access_points` - - useFIPSEndpointKey = "use_fips_endpoint" - - defaultsModeKey = "defaults_mode" - - // Retry options - retryMaxAttemptsKey = "max_attempts" - retryModeKey = "retry_mode" - - caBundleKey = "ca_bundle" - - sdkAppID = "sdk_ua_app_id" - - ignoreConfiguredEndpoints = "ignore_configured_endpoint_urls" - - endpointURL = "endpoint_url" - - servicesSectionKey = "services" - - disableRequestCompression = "disable_request_compression" - requestMinCompressionSizeBytes = "request_min_compression_size_bytes" - - s3DisableExpressSessionAuthKey = "s3_disable_express_session_auth" - - accountIDKey = "aws_account_id" - accountIDEndpointMode = "account_id_endpoint_mode" - - requestChecksumCalculationKey = "request_checksum_calculation" - responseChecksumValidationKey = "response_checksum_validation" - checksumWhenSupported = "when_supported" - checksumWhenRequired = "when_required" -) - -// defaultSharedConfigProfile allows for swapping the default profile for testing -var defaultSharedConfigProfile = DefaultSharedConfigProfile - -// DefaultSharedCredentialsFilename returns the SDK's default file path -// for the shared credentials file. -// -// Builds the shared config file path based on the OS's platform. -// -// - Linux/Unix: $HOME/.aws/credentials -// - Windows: %USERPROFILE%\.aws\credentials -func DefaultSharedCredentialsFilename() string { - return filepath.Join(shareddefaults.UserHomeDir(), ".aws", "credentials") -} - -// DefaultSharedConfigFilename returns the SDK's default file path for -// the shared config file. -// -// Builds the shared config file path based on the OS's platform. -// -// - Linux/Unix: $HOME/.aws/config -// - Windows: %USERPROFILE%\.aws\config -func DefaultSharedConfigFilename() string { - return filepath.Join(shareddefaults.UserHomeDir(), ".aws", "config") -} - -// DefaultSharedConfigFiles is a slice of the default shared config files that -// the will be used in order to load the SharedConfig. -var DefaultSharedConfigFiles = []string{ - DefaultSharedConfigFilename(), -} - -// DefaultSharedCredentialsFiles is a slice of the default shared credentials -// files that the will be used in order to load the SharedConfig. -var DefaultSharedCredentialsFiles = []string{ - DefaultSharedCredentialsFilename(), -} - -// SSOSession provides the shared configuration parameters of the sso-session -// section. -type SSOSession struct { - Name string - SSORegion string - SSOStartURL string -} - -func (s *SSOSession) setFromIniSection(section ini.Section) { - updateString(&s.Name, section, ssoSessionNameKey) - updateString(&s.SSORegion, section, ssoRegionKey) - updateString(&s.SSOStartURL, section, ssoStartURLKey) -} - -// Services contains values configured in the services section -// of the AWS configuration file. -type Services struct { - // Services section values - // {"serviceId": {"key": "value"}} - // e.g. {"s3": {"endpoint_url": "example.com"}} - ServiceValues map[string]map[string]string -} - -func (s *Services) setFromIniSection(section ini.Section) { - if s.ServiceValues == nil { - s.ServiceValues = make(map[string]map[string]string) - } - for _, service := range section.List() { - s.ServiceValues[service] = section.Map(service) - } -} - -// SharedConfig represents the configuration fields of the SDK config files. -type SharedConfig struct { - Profile string - - // Credentials values from the config file. Both aws_access_key_id - // and aws_secret_access_key must be provided together in the same file - // to be considered valid. The values will be ignored if not a complete group. - // aws_session_token is an optional field that can be provided if both of the - // other two fields are also provided. - // - // aws_access_key_id - // aws_secret_access_key - // aws_session_token - Credentials aws.Credentials - - CredentialSource string - CredentialProcess string - WebIdentityTokenFile string - - // SSO session options - SSOSessionName string - SSOSession *SSOSession - - // Legacy SSO session options - SSORegion string - SSOStartURL string - - // SSO fields not used - SSOAccountID string - SSORoleName string - - RoleARN string - ExternalID string - MFASerial string - RoleSessionName string - RoleDurationSeconds *time.Duration - - SourceProfileName string - Source *SharedConfig - - // Region is the region the SDK should use for looking up AWS service endpoints - // and signing requests. - // - // region = us-west-2 - Region string - - // EnableEndpointDiscovery can be enabled or disabled in the shared config - // by setting endpoint_discovery_enabled to true, or false respectively. - // - // endpoint_discovery_enabled = true - EnableEndpointDiscovery aws.EndpointDiscoveryEnableState - - // Specifies if the S3 service should allow ARNs to direct the region - // the client's requests are sent to. - // - // s3_use_arn_region=true - S3UseARNRegion *bool - - // Specifies the EC2 Instance Metadata Service default endpoint selection - // mode (IPv4 or IPv6) - // - // ec2_metadata_service_endpoint_mode=IPv6 - EC2IMDSEndpointMode imds.EndpointModeState - - // Specifies the EC2 Instance Metadata Service endpoint to use. If - // specified it overrides EC2IMDSEndpointMode. - // - // ec2_metadata_service_endpoint=http://fd00:ec2::254 - EC2IMDSEndpoint string - - // Specifies that IMDS clients should not fallback to IMDSv1 if token - // requests fail. - // - // ec2_metadata_v1_disabled=true - EC2IMDSv1Disabled *bool - - // Specifies if the S3 service should disable support for Multi-Region - // access-points - // - // s3_disable_multiregion_access_points=true - S3DisableMultiRegionAccessPoints *bool - - // Specifies that SDK clients must resolve a dual-stack endpoint for - // services. - // - // use_dualstack_endpoint=true - UseDualStackEndpoint aws.DualStackEndpointState - - // Specifies that SDK clients must resolve a FIPS endpoint for - // services. - // - // use_fips_endpoint=true - UseFIPSEndpoint aws.FIPSEndpointState - - // Specifies which defaults mode should be used by services. - // - // defaults_mode=standard - DefaultsMode aws.DefaultsMode - - // Specifies the maximum number attempts an API client will call an - // operation that fails with a retryable error. - // - // max_attempts=3 - RetryMaxAttempts int - - // Specifies the retry model the API client will be created with. - // - // retry_mode=standard - RetryMode aws.RetryMode - - // Sets the path to a custom Credentials Authority (CA) Bundle PEM file - // that the SDK will use instead of the system's root CA bundle. Only use - // this if you want to configure the SDK to use a custom set of CAs. - // - // Enabling this option will attempt to merge the Transport into the SDK's - // HTTP client. If the client's Transport is not a http.Transport an error - // will be returned. If the Transport's TLS config is set this option will - // cause the SDK to overwrite the Transport's TLS config's RootCAs value. - // - // Setting a custom HTTPClient in the aws.Config options will override this - // setting. To use this option and custom HTTP client, the HTTP client - // needs to be provided when creating the config. Not the service client. - // - // ca_bundle=$HOME/my_custom_ca_bundle - CustomCABundle string - - // aws sdk app ID that can be added to user agent header string - AppID string - - // Flag used to disable configured endpoints. - IgnoreConfiguredEndpoints *bool - - // Value to contain configured endpoints to be propagated to - // corresponding endpoint resolution field. - BaseEndpoint string - - // Services section config. - ServicesSectionName string - Services Services - - // determine if request compression is allowed, default to false - // retrieved from config file's profile field disable_request_compression - DisableRequestCompression *bool - - // inclusive threshold request body size to trigger compression, - // default to 10240 and must be within 0 and 10485760 bytes inclusive - // retrieved from config file's profile field request_min_compression_size_bytes - RequestMinCompressSizeBytes *int64 - - // Whether S3Express auth is disabled. - // - // This will NOT prevent requests from being made to S3Express buckets, it - // will only bypass the modified endpoint routing and signing behaviors - // associated with the feature. - S3DisableExpressAuth *bool - - AccountIDEndpointMode aws.AccountIDEndpointMode - - // RequestChecksumCalculation indicates if the request checksum should be calculated - RequestChecksumCalculation aws.RequestChecksumCalculation - - // ResponseChecksumValidation indicates if the response checksum should be validated - ResponseChecksumValidation aws.ResponseChecksumValidation -} - -func (c SharedConfig) getDefaultsMode(ctx context.Context) (value aws.DefaultsMode, ok bool, err error) { - if len(c.DefaultsMode) == 0 { - return "", false, nil - } - - return c.DefaultsMode, true, nil -} - -// GetRetryMaxAttempts returns the maximum number of attempts an API client -// created Retryer should attempt an operation call before failing. -func (c SharedConfig) GetRetryMaxAttempts(ctx context.Context) (value int, ok bool, err error) { - if c.RetryMaxAttempts == 0 { - return 0, false, nil - } - - return c.RetryMaxAttempts, true, nil -} - -// GetRetryMode returns the model the API client should create its Retryer in. -func (c SharedConfig) GetRetryMode(ctx context.Context) (value aws.RetryMode, ok bool, err error) { - if len(c.RetryMode) == 0 { - return "", false, nil - } - - return c.RetryMode, true, nil -} - -// GetS3UseARNRegion returns if the S3 service should allow ARNs to direct the region -// the client's requests are sent to. -func (c SharedConfig) GetS3UseARNRegion(ctx context.Context) (value, ok bool, err error) { - if c.S3UseARNRegion == nil { - return false, false, nil - } - - return *c.S3UseARNRegion, true, nil -} - -// GetEnableEndpointDiscovery returns if the enable_endpoint_discovery is set. -func (c SharedConfig) GetEnableEndpointDiscovery(ctx context.Context) (value aws.EndpointDiscoveryEnableState, ok bool, err error) { - if c.EnableEndpointDiscovery == aws.EndpointDiscoveryUnset { - return aws.EndpointDiscoveryUnset, false, nil - } - - return c.EnableEndpointDiscovery, true, nil -} - -// GetS3DisableMultiRegionAccessPoints returns if the S3 service should disable support for Multi-Region -// access-points. -func (c SharedConfig) GetS3DisableMultiRegionAccessPoints(ctx context.Context) (value, ok bool, err error) { - if c.S3DisableMultiRegionAccessPoints == nil { - return false, false, nil - } - - return *c.S3DisableMultiRegionAccessPoints, true, nil -} - -// GetRegion returns the region for the profile if a region is set. -func (c SharedConfig) getRegion(ctx context.Context) (string, bool, error) { - if len(c.Region) == 0 { - return "", false, nil - } - return c.Region, true, nil -} - -// GetCredentialsProvider returns the credentials for a profile if they were set. -func (c SharedConfig) getCredentialsProvider() (aws.Credentials, bool, error) { - return c.Credentials, true, nil -} - -// GetEC2IMDSEndpointMode implements a EC2IMDSEndpointMode option resolver interface. -func (c SharedConfig) GetEC2IMDSEndpointMode() (imds.EndpointModeState, bool, error) { - if c.EC2IMDSEndpointMode == imds.EndpointModeStateUnset { - return imds.EndpointModeStateUnset, false, nil - } - - return c.EC2IMDSEndpointMode, true, nil -} - -// GetEC2IMDSEndpoint implements a EC2IMDSEndpoint option resolver interface. -func (c SharedConfig) GetEC2IMDSEndpoint() (string, bool, error) { - if len(c.EC2IMDSEndpoint) == 0 { - return "", false, nil - } - - return c.EC2IMDSEndpoint, true, nil -} - -// GetEC2IMDSV1FallbackDisabled implements an EC2IMDSV1FallbackDisabled option -// resolver interface. -func (c SharedConfig) GetEC2IMDSV1FallbackDisabled() (bool, bool) { - if c.EC2IMDSv1Disabled == nil { - return false, false - } - - return *c.EC2IMDSv1Disabled, true -} - -// GetUseDualStackEndpoint returns whether the service's dual-stack endpoint should be -// used for requests. -func (c SharedConfig) GetUseDualStackEndpoint(ctx context.Context) (value aws.DualStackEndpointState, found bool, err error) { - if c.UseDualStackEndpoint == aws.DualStackEndpointStateUnset { - return aws.DualStackEndpointStateUnset, false, nil - } - - return c.UseDualStackEndpoint, true, nil -} - -// GetUseFIPSEndpoint returns whether the service's FIPS endpoint should be -// used for requests. -func (c SharedConfig) GetUseFIPSEndpoint(ctx context.Context) (value aws.FIPSEndpointState, found bool, err error) { - if c.UseFIPSEndpoint == aws.FIPSEndpointStateUnset { - return aws.FIPSEndpointStateUnset, false, nil - } - - return c.UseFIPSEndpoint, true, nil -} - -// GetS3DisableExpressAuth returns the configured value for -// [SharedConfig.S3DisableExpressAuth]. -func (c SharedConfig) GetS3DisableExpressAuth() (value, ok bool) { - if c.S3DisableExpressAuth == nil { - return false, false - } - - return *c.S3DisableExpressAuth, true -} - -// GetCustomCABundle returns the custom CA bundle's PEM bytes if the file was -func (c SharedConfig) getCustomCABundle(context.Context) (io.Reader, bool, error) { - if len(c.CustomCABundle) == 0 { - return nil, false, nil - } - - b, err := ioutil.ReadFile(c.CustomCABundle) - if err != nil { - return nil, false, err - } - return bytes.NewReader(b), true, nil -} - -// getAppID returns the sdk app ID if set in shared config profile -func (c SharedConfig) getAppID(context.Context) (string, bool, error) { - return c.AppID, len(c.AppID) > 0, nil -} - -// GetIgnoreConfiguredEndpoints is used in knowing when to disable configured -// endpoints feature. -func (c SharedConfig) GetIgnoreConfiguredEndpoints(context.Context) (bool, bool, error) { - if c.IgnoreConfiguredEndpoints == nil { - return false, false, nil - } - - return *c.IgnoreConfiguredEndpoints, true, nil -} - -func (c SharedConfig) getBaseEndpoint(context.Context) (string, bool, error) { - return c.BaseEndpoint, len(c.BaseEndpoint) > 0, nil -} - -// GetServiceBaseEndpoint is used to retrieve a normalized SDK ID for use -// with configured endpoints. -func (c SharedConfig) GetServiceBaseEndpoint(ctx context.Context, sdkID string) (string, bool, error) { - if service, ok := c.Services.ServiceValues[normalizeShared(sdkID)]; ok { - if endpt, ok := service[endpointURL]; ok { - return endpt, true, nil - } - } - return "", false, nil -} - -func normalizeShared(sdkID string) string { - lower := strings.ToLower(sdkID) - return strings.ReplaceAll(lower, " ", "_") -} - -func (c SharedConfig) getServicesObject(context.Context) (map[string]map[string]string, bool, error) { - return c.Services.ServiceValues, c.Services.ServiceValues != nil, nil -} - -// loadSharedConfigIgnoreNotExist is an alias for loadSharedConfig with the -// addition of ignoring when none of the files exist or when the profile -// is not found in any of the files. -func loadSharedConfigIgnoreNotExist(ctx context.Context, configs configs) (Config, error) { - cfg, err := loadSharedConfig(ctx, configs) - if err != nil { - if _, ok := err.(SharedConfigProfileNotExistError); ok { - return SharedConfig{}, nil - } - return nil, err - } - - return cfg, nil -} - -// loadSharedConfig uses the configs passed in to load the SharedConfig from file -// The file names and profile name are sourced from the configs. -// -// If profile name is not provided DefaultSharedConfigProfile (default) will -// be used. -// -// If shared config filenames are not provided DefaultSharedConfigFiles will -// be used. -// -// Config providers used: -// * sharedConfigProfileProvider -// * sharedConfigFilesProvider -func loadSharedConfig(ctx context.Context, configs configs) (Config, error) { - var profile string - var configFiles []string - var credentialsFiles []string - var ok bool - var err error - - profile, ok, err = getSharedConfigProfile(ctx, configs) - if err != nil { - return nil, err - } - if !ok { - profile = defaultSharedConfigProfile - } - - configFiles, ok, err = getSharedConfigFiles(ctx, configs) - if err != nil { - return nil, err - } - - credentialsFiles, ok, err = getSharedCredentialsFiles(ctx, configs) - if err != nil { - return nil, err - } - - // setup logger if log configuration warning is seti - var logger logging.Logger - logWarnings, found, err := getLogConfigurationWarnings(ctx, configs) - if err != nil { - return SharedConfig{}, err - } - if found && logWarnings { - logger, found, err = getLogger(ctx, configs) - if err != nil { - return SharedConfig{}, err - } - if !found { - logger = logging.NewStandardLogger(os.Stderr) - } - } - - return LoadSharedConfigProfile(ctx, profile, - func(o *LoadSharedConfigOptions) { - o.Logger = logger - o.ConfigFiles = configFiles - o.CredentialsFiles = credentialsFiles - }, - ) -} - -// LoadSharedConfigOptions struct contains optional values that can be used to load the config. -type LoadSharedConfigOptions struct { - - // CredentialsFiles are the shared credentials files - CredentialsFiles []string - - // ConfigFiles are the shared config files - ConfigFiles []string - - // Logger is the logger used to log shared config behavior - Logger logging.Logger -} - -// LoadSharedConfigProfile retrieves the configuration from the list of files -// using the profile provided. The order the files are listed will determine -// precedence. Values in subsequent files will overwrite values defined in -// earlier files. -// -// For example, given two files A and B. Both define credentials. If the order -// of the files are A then B, B's credential values will be used instead of A's. -// -// If config files are not set, SDK will default to using a file at location `.aws/config` if present. -// If credentials files are not set, SDK will default to using a file at location `.aws/credentials` if present. -// No default files are set, if files set to an empty slice. -// -// You can read more about shared config and credentials file location at -// https://docs.aws.amazon.com/credref/latest/refdocs/file-location.html#file-location -func LoadSharedConfigProfile(ctx context.Context, profile string, optFns ...func(*LoadSharedConfigOptions)) (SharedConfig, error) { - var option LoadSharedConfigOptions - for _, fn := range optFns { - fn(&option) - } - - if option.ConfigFiles == nil { - option.ConfigFiles = DefaultSharedConfigFiles - } - - if option.CredentialsFiles == nil { - option.CredentialsFiles = DefaultSharedCredentialsFiles - } - - // load shared configuration sections from shared configuration INI options - configSections, err := loadIniFiles(option.ConfigFiles) - if err != nil { - return SharedConfig{}, err - } - - // check for profile prefix and drop duplicates or invalid profiles - err = processConfigSections(ctx, &configSections, option.Logger) - if err != nil { - return SharedConfig{}, err - } - - // load shared credentials sections from shared credentials INI options - credentialsSections, err := loadIniFiles(option.CredentialsFiles) - if err != nil { - return SharedConfig{}, err - } - - // check for profile prefix and drop duplicates or invalid profiles - err = processCredentialsSections(ctx, &credentialsSections, option.Logger) - if err != nil { - return SharedConfig{}, err - } - - err = mergeSections(&configSections, credentialsSections) - if err != nil { - return SharedConfig{}, err - } - - cfg := SharedConfig{} - profiles := map[string]struct{}{} - - if err = cfg.setFromIniSections(profiles, profile, configSections, option.Logger); err != nil { - return SharedConfig{}, err - } - - return cfg, nil -} - -func processConfigSections(ctx context.Context, sections *ini.Sections, logger logging.Logger) error { - skipSections := map[string]struct{}{} - - for _, section := range sections.List() { - if _, ok := skipSections[section]; ok { - continue - } - - // drop sections from config file that do not have expected prefixes. - switch { - case strings.HasPrefix(section, profilePrefix): - // Rename sections to remove "profile " prefixing to match with - // credentials file. If default is already present, it will be - // dropped. - newName, err := renameProfileSection(section, sections, logger) - if err != nil { - return fmt.Errorf("failed to rename profile section, %w", err) - } - skipSections[newName] = struct{}{} - - case strings.HasPrefix(section, ssoSectionPrefix): - case strings.HasPrefix(section, servicesPrefix): - case strings.EqualFold(section, "default"): - default: - // drop this section, as invalid profile name - sections.DeleteSection(section) - - if logger != nil { - logger.Logf(logging.Debug, "A profile defined with name `%v` is ignored. "+ - "For use within a shared configuration file, "+ - "a non-default profile must have `profile ` "+ - "prefixed to the profile name.", - section, - ) - } - } - } - return nil -} - -func renameProfileSection(section string, sections *ini.Sections, logger logging.Logger) (string, error) { - v, ok := sections.GetSection(section) - if !ok { - return "", fmt.Errorf("error processing profiles within the shared configuration files") - } - - // delete section with profile as prefix - sections.DeleteSection(section) - - // set the value to non-prefixed name in sections. - section = strings.TrimPrefix(section, profilePrefix) - if sections.HasSection(section) { - oldSection, _ := sections.GetSection(section) - v.Logs = append(v.Logs, - fmt.Sprintf("A non-default profile not prefixed with `profile ` found in %s, "+ - "overriding non-default profile from %s", - v.SourceFile, oldSection.SourceFile)) - sections.DeleteSection(section) - } - - // assign non-prefixed name to section - v.Name = section - sections.SetSection(section, v) - - return section, nil -} - -func processCredentialsSections(ctx context.Context, sections *ini.Sections, logger logging.Logger) error { - for _, section := range sections.List() { - // drop profiles with prefix for credential files - if strings.HasPrefix(section, profilePrefix) { - // drop this section, as invalid profile name - sections.DeleteSection(section) - - if logger != nil { - logger.Logf(logging.Debug, - "The profile defined with name `%v` is ignored. A profile with the `profile ` prefix is invalid "+ - "for the shared credentials file.\n", - section, - ) - } - } - } - return nil -} - -func loadIniFiles(filenames []string) (ini.Sections, error) { - mergedSections := ini.NewSections() - - for _, filename := range filenames { - sections, err := ini.OpenFile(filename) - var v *ini.UnableToReadFile - if ok := errors.As(err, &v); ok { - // Skip files which can't be opened and read for whatever reason. - // We treat such files as empty, and do not fall back to other locations. - continue - } else if err != nil { - return ini.Sections{}, SharedConfigLoadError{Filename: filename, Err: err} - } - - // mergeSections into mergedSections - err = mergeSections(&mergedSections, sections) - if err != nil { - return ini.Sections{}, SharedConfigLoadError{Filename: filename, Err: err} - } - } - - return mergedSections, nil -} - -// mergeSections merges source section properties into destination section properties -func mergeSections(dst *ini.Sections, src ini.Sections) error { - for _, sectionName := range src.List() { - srcSection, _ := src.GetSection(sectionName) - - if (!srcSection.Has(accessKeyIDKey) && srcSection.Has(secretAccessKey)) || - (srcSection.Has(accessKeyIDKey) && !srcSection.Has(secretAccessKey)) { - srcSection.Errors = append(srcSection.Errors, - fmt.Errorf("partial credentials found for profile %v", sectionName)) - } - - if !dst.HasSection(sectionName) { - dst.SetSection(sectionName, srcSection) - continue - } - - // merge with destination srcSection - dstSection, _ := dst.GetSection(sectionName) - - // errors should be overriden if any - dstSection.Errors = srcSection.Errors - - // Access key id update - if srcSection.Has(accessKeyIDKey) && srcSection.Has(secretAccessKey) { - accessKey := srcSection.String(accessKeyIDKey) - secretKey := srcSection.String(secretAccessKey) - - if dstSection.Has(accessKeyIDKey) { - dstSection.Logs = append(dstSection.Logs, newMergeKeyLogMessage(sectionName, accessKeyIDKey, - dstSection.SourceFile[accessKeyIDKey], srcSection.SourceFile[accessKeyIDKey])) - } - - // update access key - v, err := ini.NewStringValue(accessKey) - if err != nil { - return fmt.Errorf("error merging access key, %w", err) - } - dstSection.UpdateValue(accessKeyIDKey, v) - - // update secret key - v, err = ini.NewStringValue(secretKey) - if err != nil { - return fmt.Errorf("error merging secret key, %w", err) - } - dstSection.UpdateValue(secretAccessKey, v) - - // update session token - if err = mergeStringKey(&srcSection, &dstSection, sectionName, sessionTokenKey); err != nil { - return err - } - - // update source file to reflect where the static creds came from - dstSection.UpdateSourceFile(accessKeyIDKey, srcSection.SourceFile[accessKeyIDKey]) - dstSection.UpdateSourceFile(secretAccessKey, srcSection.SourceFile[secretAccessKey]) - } - - stringKeys := []string{ - roleArnKey, - sourceProfileKey, - credentialSourceKey, - externalIDKey, - mfaSerialKey, - roleSessionNameKey, - regionKey, - enableEndpointDiscoveryKey, - credentialProcessKey, - webIdentityTokenFileKey, - s3UseARNRegionKey, - s3DisableMultiRegionAccessPointsKey, - ec2MetadataServiceEndpointModeKey, - ec2MetadataServiceEndpointKey, - ec2MetadataV1DisabledKey, - useDualStackEndpoint, - useFIPSEndpointKey, - defaultsModeKey, - retryModeKey, - caBundleKey, - roleDurationSecondsKey, - retryMaxAttemptsKey, - - ssoSessionNameKey, - ssoAccountIDKey, - ssoRegionKey, - ssoRoleNameKey, - ssoStartURLKey, - } - for i := range stringKeys { - if err := mergeStringKey(&srcSection, &dstSection, sectionName, stringKeys[i]); err != nil { - return err - } - } - - // set srcSection on dst srcSection - *dst = dst.SetSection(sectionName, dstSection) - } - - return nil -} - -func mergeStringKey(srcSection *ini.Section, dstSection *ini.Section, sectionName, key string) error { - if srcSection.Has(key) { - srcValue := srcSection.String(key) - val, err := ini.NewStringValue(srcValue) - if err != nil { - return fmt.Errorf("error merging %s, %w", key, err) - } - - if dstSection.Has(key) { - dstSection.Logs = append(dstSection.Logs, newMergeKeyLogMessage(sectionName, key, - dstSection.SourceFile[key], srcSection.SourceFile[key])) - } - - dstSection.UpdateValue(key, val) - dstSection.UpdateSourceFile(key, srcSection.SourceFile[key]) - } - return nil -} - -func newMergeKeyLogMessage(sectionName, key, dstSourceFile, srcSourceFile string) string { - return fmt.Sprintf("For profile: %v, overriding %v value, defined in %v "+ - "with a %v value found in a duplicate profile defined at file %v. \n", - sectionName, key, dstSourceFile, key, srcSourceFile) -} - -// Returns an error if all of the files fail to load. If at least one file is -// successfully loaded and contains the profile, no error will be returned. -func (c *SharedConfig) setFromIniSections(profiles map[string]struct{}, profile string, - sections ini.Sections, logger logging.Logger) error { - c.Profile = profile - - section, ok := sections.GetSection(profile) - if !ok { - return SharedConfigProfileNotExistError{ - Profile: profile, - } - } - - // if logs are appended to the section, log them - if section.Logs != nil && logger != nil { - for _, log := range section.Logs { - logger.Logf(logging.Debug, log) - } - } - - // set config from the provided INI section - err := c.setFromIniSection(profile, section) - if err != nil { - return fmt.Errorf("error fetching config from profile, %v, %w", profile, err) - } - - if _, ok := profiles[profile]; ok { - // if this is the second instance of the profile the Assume Role - // options must be cleared because they are only valid for the - // first reference of a profile. The self linked instance of the - // profile only have credential provider options. - c.clearAssumeRoleOptions() - } else { - // First time a profile has been seen. Assert if the credential type - // requires a role ARN, the ARN is also set - if err := c.validateCredentialsConfig(profile); err != nil { - return err - } - } - - // if not top level profile and has credentials, return with credentials. - if len(profiles) != 0 && c.Credentials.HasKeys() { - return nil - } - - profiles[profile] = struct{}{} - - // validate no colliding credentials type are present - if err := c.validateCredentialType(); err != nil { - return err - } - - // Link source profiles for assume roles - if len(c.SourceProfileName) != 0 { - // Linked profile via source_profile ignore credential provider - // options, the source profile must provide the credentials. - c.clearCredentialOptions() - - srcCfg := &SharedConfig{} - err := srcCfg.setFromIniSections(profiles, c.SourceProfileName, sections, logger) - if err != nil { - // SourceProfileName that doesn't exist is an error in configuration. - if _, ok := err.(SharedConfigProfileNotExistError); ok { - err = SharedConfigAssumeRoleError{ - RoleARN: c.RoleARN, - Profile: c.SourceProfileName, - Err: err, - } - } - return err - } - - if !srcCfg.hasCredentials() { - return SharedConfigAssumeRoleError{ - RoleARN: c.RoleARN, - Profile: c.SourceProfileName, - } - } - - c.Source = srcCfg - } - - // If the profile contains an SSO session parameter, the session MUST exist - // as a section in the config file. Load the SSO session using the name - // provided. If the session section is not found or incomplete an error - // will be returned. - if c.hasSSOTokenProviderConfiguration() { - section, ok := sections.GetSection(ssoSectionPrefix + strings.TrimSpace(c.SSOSessionName)) - if !ok { - return fmt.Errorf("failed to find SSO session section, %v", c.SSOSessionName) - } - var ssoSession SSOSession - ssoSession.setFromIniSection(section) - ssoSession.Name = c.SSOSessionName - c.SSOSession = &ssoSession - } - - if len(c.ServicesSectionName) > 0 { - if section, ok := sections.GetSection(servicesPrefix + c.ServicesSectionName); ok { - var svcs Services - svcs.setFromIniSection(section) - c.Services = svcs - } - } - - return nil -} - -// setFromIniSection loads the configuration from the profile section defined in -// the provided INI file. A SharedConfig pointer type value is used so that -// multiple config file loadings can be chained. -// -// Only loads complete logically grouped values, and will not set fields in cfg -// for incomplete grouped values in the config. Such as credentials. For example -// if a config file only includes aws_access_key_id but no aws_secret_access_key -// the aws_access_key_id will be ignored. -func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) error { - if len(section.Name) == 0 { - sources := make([]string, 0) - for _, v := range section.SourceFile { - sources = append(sources, v) - } - - return fmt.Errorf("parsing error : could not find profile section name after processing files: %v", sources) - } - - if len(section.Errors) != 0 { - var errStatement string - for i, e := range section.Errors { - errStatement = fmt.Sprintf("%d, %v\n", i+1, e.Error()) - } - return fmt.Errorf("Error using profile: \n %v", errStatement) - } - - // Assume Role - updateString(&c.RoleARN, section, roleArnKey) - updateString(&c.ExternalID, section, externalIDKey) - updateString(&c.MFASerial, section, mfaSerialKey) - updateString(&c.RoleSessionName, section, roleSessionNameKey) - updateString(&c.SourceProfileName, section, sourceProfileKey) - updateString(&c.CredentialSource, section, credentialSourceKey) - updateString(&c.Region, section, regionKey) - - // AWS Single Sign-On (AWS SSO) - // SSO session options - updateString(&c.SSOSessionName, section, ssoSessionNameKey) - - // Legacy SSO session options - updateString(&c.SSORegion, section, ssoRegionKey) - updateString(&c.SSOStartURL, section, ssoStartURLKey) - - // SSO fields not used - updateString(&c.SSOAccountID, section, ssoAccountIDKey) - updateString(&c.SSORoleName, section, ssoRoleNameKey) - - // we're retaining a behavioral quirk with this field that existed before - // the removal of literal parsing for #2276: - // - if the key is missing, the config field will not be set - // - if the key is set to a non-numeric, the config field will be set to 0 - if section.Has(roleDurationSecondsKey) { - if v, ok := section.Int(roleDurationSecondsKey); ok { - c.RoleDurationSeconds = aws.Duration(time.Duration(v) * time.Second) - } else { - c.RoleDurationSeconds = aws.Duration(time.Duration(0)) - } - } - - updateString(&c.CredentialProcess, section, credentialProcessKey) - updateString(&c.WebIdentityTokenFile, section, webIdentityTokenFileKey) - - updateEndpointDiscoveryType(&c.EnableEndpointDiscovery, section, enableEndpointDiscoveryKey) - updateBoolPtr(&c.S3UseARNRegion, section, s3UseARNRegionKey) - updateBoolPtr(&c.S3DisableMultiRegionAccessPoints, section, s3DisableMultiRegionAccessPointsKey) - updateBoolPtr(&c.S3DisableExpressAuth, section, s3DisableExpressSessionAuthKey) - - if err := updateEC2MetadataServiceEndpointMode(&c.EC2IMDSEndpointMode, section, ec2MetadataServiceEndpointModeKey); err != nil { - return fmt.Errorf("failed to load %s from shared config, %v", ec2MetadataServiceEndpointModeKey, err) - } - updateString(&c.EC2IMDSEndpoint, section, ec2MetadataServiceEndpointKey) - updateBoolPtr(&c.EC2IMDSv1Disabled, section, ec2MetadataV1DisabledKey) - - updateUseDualStackEndpoint(&c.UseDualStackEndpoint, section, useDualStackEndpoint) - updateUseFIPSEndpoint(&c.UseFIPSEndpoint, section, useFIPSEndpointKey) - - if err := updateDefaultsMode(&c.DefaultsMode, section, defaultsModeKey); err != nil { - return fmt.Errorf("failed to load %s from shared config, %w", defaultsModeKey, err) - } - - if err := updateInt(&c.RetryMaxAttempts, section, retryMaxAttemptsKey); err != nil { - return fmt.Errorf("failed to load %s from shared config, %w", retryMaxAttemptsKey, err) - } - if err := updateRetryMode(&c.RetryMode, section, retryModeKey); err != nil { - return fmt.Errorf("failed to load %s from shared config, %w", retryModeKey, err) - } - - updateString(&c.CustomCABundle, section, caBundleKey) - - // user agent app ID added to request User-Agent header - updateString(&c.AppID, section, sdkAppID) - - updateBoolPtr(&c.IgnoreConfiguredEndpoints, section, ignoreConfiguredEndpoints) - - updateString(&c.BaseEndpoint, section, endpointURL) - - if err := updateDisableRequestCompression(&c.DisableRequestCompression, section, disableRequestCompression); err != nil { - return fmt.Errorf("failed to load %s from shared config, %w", disableRequestCompression, err) - } - if err := updateRequestMinCompressSizeBytes(&c.RequestMinCompressSizeBytes, section, requestMinCompressionSizeBytes); err != nil { - return fmt.Errorf("failed to load %s from shared config, %w", requestMinCompressionSizeBytes, err) - } - - if err := updateAIDEndpointMode(&c.AccountIDEndpointMode, section, accountIDEndpointMode); err != nil { - return fmt.Errorf("failed to load %s from shared config, %w", accountIDEndpointMode, err) - } - - if err := updateRequestChecksumCalculation(&c.RequestChecksumCalculation, section, requestChecksumCalculationKey); err != nil { - return fmt.Errorf("failed to load %s from shared config, %w", requestChecksumCalculationKey, err) - } - if err := updateResponseChecksumValidation(&c.ResponseChecksumValidation, section, responseChecksumValidationKey); err != nil { - return fmt.Errorf("failed to load %s from shared config, %w", responseChecksumValidationKey, err) - } - - // Shared Credentials - creds := aws.Credentials{ - AccessKeyID: section.String(accessKeyIDKey), - SecretAccessKey: section.String(secretAccessKey), - SessionToken: section.String(sessionTokenKey), - Source: fmt.Sprintf("SharedConfigCredentials: %s", section.SourceFile[accessKeyIDKey]), - AccountID: section.String(accountIDKey), - } - - if creds.HasKeys() { - c.Credentials = creds - } - - updateString(&c.ServicesSectionName, section, servicesSectionKey) - - return nil -} - -func updateRequestMinCompressSizeBytes(bytes **int64, sec ini.Section, key string) error { - if !sec.Has(key) { - return nil - } - - v, ok := sec.Int(key) - if !ok { - return fmt.Errorf("invalid value for min request compression size bytes %s, need int64", sec.String(key)) - } - if v < 0 || v > smithyrequestcompression.MaxRequestMinCompressSizeBytes { - return fmt.Errorf("invalid range for min request compression size bytes %d, must be within 0 and 10485760 inclusively", v) - } - *bytes = new(int64) - **bytes = v - return nil -} - -func updateDisableRequestCompression(disable **bool, sec ini.Section, key string) error { - if !sec.Has(key) { - return nil - } - - v := sec.String(key) - switch { - case v == "true": - *disable = new(bool) - **disable = true - case v == "false": - *disable = new(bool) - **disable = false - default: - return fmt.Errorf("invalid value for shared config profile field, %s=%s, need true or false", key, v) - } - return nil -} - -func updateAIDEndpointMode(m *aws.AccountIDEndpointMode, sec ini.Section, key string) error { - if !sec.Has(key) { - return nil - } - - v := sec.String(key) - switch v { - case "preferred": - *m = aws.AccountIDEndpointModePreferred - case "required": - *m = aws.AccountIDEndpointModeRequired - case "disabled": - *m = aws.AccountIDEndpointModeDisabled - default: - return fmt.Errorf("invalid value for shared config profile field, %s=%s, must be preferred/required/disabled", key, v) - } - - return nil -} - -func updateRequestChecksumCalculation(m *aws.RequestChecksumCalculation, sec ini.Section, key string) error { - if !sec.Has(key) { - return nil - } - - v := sec.String(key) - switch strings.ToLower(v) { - case checksumWhenSupported: - *m = aws.RequestChecksumCalculationWhenSupported - case checksumWhenRequired: - *m = aws.RequestChecksumCalculationWhenRequired - default: - return fmt.Errorf("invalid value for shared config profile field, %s=%s, must be when_supported/when_required", key, v) - } - - return nil -} - -func updateResponseChecksumValidation(m *aws.ResponseChecksumValidation, sec ini.Section, key string) error { - if !sec.Has(key) { - return nil - } - - v := sec.String(key) - switch strings.ToLower(v) { - case checksumWhenSupported: - *m = aws.ResponseChecksumValidationWhenSupported - case checksumWhenRequired: - *m = aws.ResponseChecksumValidationWhenRequired - default: - return fmt.Errorf("invalid value for shared config profile field, %s=%s, must be when_supported/when_required", key, v) - } - - return nil -} - -func (c SharedConfig) getRequestMinCompressSizeBytes(ctx context.Context) (int64, bool, error) { - if c.RequestMinCompressSizeBytes == nil { - return 0, false, nil - } - return *c.RequestMinCompressSizeBytes, true, nil -} - -func (c SharedConfig) getDisableRequestCompression(ctx context.Context) (bool, bool, error) { - if c.DisableRequestCompression == nil { - return false, false, nil - } - return *c.DisableRequestCompression, true, nil -} - -func (c SharedConfig) getAccountIDEndpointMode(ctx context.Context) (aws.AccountIDEndpointMode, bool, error) { - return c.AccountIDEndpointMode, len(c.AccountIDEndpointMode) > 0, nil -} - -func (c SharedConfig) getRequestChecksumCalculation(ctx context.Context) (aws.RequestChecksumCalculation, bool, error) { - return c.RequestChecksumCalculation, c.RequestChecksumCalculation > 0, nil -} - -func (c SharedConfig) getResponseChecksumValidation(ctx context.Context) (aws.ResponseChecksumValidation, bool, error) { - return c.ResponseChecksumValidation, c.ResponseChecksumValidation > 0, nil -} - -func updateDefaultsMode(mode *aws.DefaultsMode, section ini.Section, key string) error { - if !section.Has(key) { - return nil - } - value := section.String(key) - if ok := mode.SetFromString(value); !ok { - return fmt.Errorf("invalid value: %s", value) - } - return nil -} - -func updateRetryMode(mode *aws.RetryMode, section ini.Section, key string) (err error) { - if !section.Has(key) { - return nil - } - value := section.String(key) - if *mode, err = aws.ParseRetryMode(value); err != nil { - return err - } - return nil -} - -func updateEC2MetadataServiceEndpointMode(endpointMode *imds.EndpointModeState, section ini.Section, key string) error { - if !section.Has(key) { - return nil - } - value := section.String(key) - return endpointMode.SetFromString(value) -} - -func (c *SharedConfig) validateCredentialsConfig(profile string) error { - if err := c.validateCredentialsRequireARN(profile); err != nil { - return err - } - - return nil -} - -func (c *SharedConfig) validateCredentialsRequireARN(profile string) error { - var credSource string - - switch { - case len(c.SourceProfileName) != 0: - credSource = sourceProfileKey - case len(c.CredentialSource) != 0: - credSource = credentialSourceKey - case len(c.WebIdentityTokenFile) != 0: - credSource = webIdentityTokenFileKey - } - - if len(credSource) != 0 && len(c.RoleARN) == 0 { - return CredentialRequiresARNError{ - Type: credSource, - Profile: profile, - } - } - - return nil -} - -func (c *SharedConfig) validateCredentialType() error { - // Only one or no credential type can be defined. - if !oneOrNone( - len(c.SourceProfileName) != 0, - len(c.CredentialSource) != 0, - len(c.CredentialProcess) != 0, - len(c.WebIdentityTokenFile) != 0, - ) { - return fmt.Errorf("only one credential type may be specified per profile: source profile, credential source, credential process, web identity token") - } - - return nil -} - -func (c *SharedConfig) validateSSOConfiguration() error { - if c.hasSSOTokenProviderConfiguration() { - err := c.validateSSOTokenProviderConfiguration() - if err != nil { - return err - } - return nil - } - - if c.hasLegacySSOConfiguration() { - err := c.validateLegacySSOConfiguration() - if err != nil { - return err - } - } - return nil -} - -func (c *SharedConfig) validateSSOTokenProviderConfiguration() error { - var missing []string - - if len(c.SSOSessionName) == 0 { - missing = append(missing, ssoSessionNameKey) - } - - if c.SSOSession == nil { - missing = append(missing, ssoSectionPrefix) - } else { - if len(c.SSOSession.SSORegion) == 0 { - missing = append(missing, ssoRegionKey) - } - - if len(c.SSOSession.SSOStartURL) == 0 { - missing = append(missing, ssoStartURLKey) - } - } - - if len(missing) > 0 { - return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s", - c.Profile, strings.Join(missing, ", ")) - } - - if len(c.SSORegion) > 0 && c.SSORegion != c.SSOSession.SSORegion { - return fmt.Errorf("%s in profile %q must match %s in %s", ssoRegionKey, c.Profile, ssoRegionKey, ssoSectionPrefix) - } - - if len(c.SSOStartURL) > 0 && c.SSOStartURL != c.SSOSession.SSOStartURL { - return fmt.Errorf("%s in profile %q must match %s in %s", ssoStartURLKey, c.Profile, ssoStartURLKey, ssoSectionPrefix) - } - - return nil -} - -func (c *SharedConfig) validateLegacySSOConfiguration() error { - var missing []string - - if len(c.SSORegion) == 0 { - missing = append(missing, ssoRegionKey) - } - - if len(c.SSOStartURL) == 0 { - missing = append(missing, ssoStartURLKey) - } - - if len(c.SSOAccountID) == 0 { - missing = append(missing, ssoAccountIDKey) - } - - if len(c.SSORoleName) == 0 { - missing = append(missing, ssoRoleNameKey) - } - - if len(missing) > 0 { - return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s", - c.Profile, strings.Join(missing, ", ")) - } - return nil -} - -func (c *SharedConfig) hasCredentials() bool { - switch { - case len(c.SourceProfileName) != 0: - case len(c.CredentialSource) != 0: - case len(c.CredentialProcess) != 0: - case len(c.WebIdentityTokenFile) != 0: - case c.hasSSOConfiguration(): - case c.Credentials.HasKeys(): - default: - return false - } - - return true -} - -func (c *SharedConfig) hasSSOConfiguration() bool { - return c.hasSSOTokenProviderConfiguration() || c.hasLegacySSOConfiguration() -} - -func (c *SharedConfig) hasSSOTokenProviderConfiguration() bool { - return len(c.SSOSessionName) > 0 -} - -func (c *SharedConfig) hasLegacySSOConfiguration() bool { - return len(c.SSORegion) > 0 || len(c.SSOAccountID) > 0 || len(c.SSOStartURL) > 0 || len(c.SSORoleName) > 0 -} - -func (c *SharedConfig) clearAssumeRoleOptions() { - c.RoleARN = "" - c.ExternalID = "" - c.MFASerial = "" - c.RoleSessionName = "" - c.SourceProfileName = "" -} - -func (c *SharedConfig) clearCredentialOptions() { - c.CredentialSource = "" - c.CredentialProcess = "" - c.WebIdentityTokenFile = "" - c.Credentials = aws.Credentials{} - c.SSOAccountID = "" - c.SSORegion = "" - c.SSORoleName = "" - c.SSOStartURL = "" -} - -// SharedConfigLoadError is an error for the shared config file failed to load. -type SharedConfigLoadError struct { - Filename string - Err error -} - -// Unwrap returns the underlying error that caused the failure. -func (e SharedConfigLoadError) Unwrap() error { - return e.Err -} - -func (e SharedConfigLoadError) Error() string { - return fmt.Sprintf("failed to load shared config file, %s, %v", e.Filename, e.Err) -} - -// SharedConfigProfileNotExistError is an error for the shared config when -// the profile was not find in the config file. -type SharedConfigProfileNotExistError struct { - Filename []string - Profile string - Err error -} - -// Unwrap returns the underlying error that caused the failure. -func (e SharedConfigProfileNotExistError) Unwrap() error { - return e.Err -} - -func (e SharedConfigProfileNotExistError) Error() string { - return fmt.Sprintf("failed to get shared config profile, %s", e.Profile) -} - -// SharedConfigAssumeRoleError is an error for the shared config when the -// profile contains assume role information, but that information is invalid -// or not complete. -type SharedConfigAssumeRoleError struct { - Profile string - RoleARN string - Err error -} - -// Unwrap returns the underlying error that caused the failure. -func (e SharedConfigAssumeRoleError) Unwrap() error { - return e.Err -} - -func (e SharedConfigAssumeRoleError) Error() string { - return fmt.Sprintf("failed to load assume role %s, of profile %s, %v", - e.RoleARN, e.Profile, e.Err) -} - -// CredentialRequiresARNError provides the error for shared config credentials -// that are incorrectly configured in the shared config or credentials file. -type CredentialRequiresARNError struct { - // type of credentials that were configured. - Type string - - // Profile name the credentials were in. - Profile string -} - -// Error satisfies the error interface. -func (e CredentialRequiresARNError) Error() string { - return fmt.Sprintf( - "credential type %s requires role_arn, profile %s", - e.Type, e.Profile, - ) -} - -func oneOrNone(bs ...bool) bool { - var count int - - for _, b := range bs { - if b { - count++ - if count > 1 { - return false - } - } - } - - return true -} - -// updateString will only update the dst with the value in the section key, key -// is present in the section. -func updateString(dst *string, section ini.Section, key string) { - if !section.Has(key) { - return - } - *dst = section.String(key) -} - -// updateInt will only update the dst with the value in the section key, key -// is present in the section. -// -// Down casts the INI integer value from a int64 to an int, which could be -// different bit size depending on platform. -func updateInt(dst *int, section ini.Section, key string) error { - if !section.Has(key) { - return nil - } - - v, ok := section.Int(key) - if !ok { - return fmt.Errorf("invalid value %s=%s, expect integer", key, section.String(key)) - } - - *dst = int(v) - return nil -} - -// updateBool will only update the dst with the value in the section key, key -// is present in the section. -func updateBool(dst *bool, section ini.Section, key string) { - if !section.Has(key) { - return - } - - // retains pre-#2276 behavior where non-bool value would resolve to false - v, _ := section.Bool(key) - *dst = v -} - -// updateBoolPtr will only update the dst with the value in the section key, -// key is present in the section. -func updateBoolPtr(dst **bool, section ini.Section, key string) { - if !section.Has(key) { - return - } - - // retains pre-#2276 behavior where non-bool value would resolve to false - v, _ := section.Bool(key) - *dst = new(bool) - **dst = v -} - -// updateEndpointDiscoveryType will only update the dst with the value in the section, if -// a valid key and corresponding EndpointDiscoveryType is found. -func updateEndpointDiscoveryType(dst *aws.EndpointDiscoveryEnableState, section ini.Section, key string) { - if !section.Has(key) { - return - } - - value := section.String(key) - if len(value) == 0 { - return - } - - switch { - case strings.EqualFold(value, endpointDiscoveryDisabled): - *dst = aws.EndpointDiscoveryDisabled - case strings.EqualFold(value, endpointDiscoveryEnabled): - *dst = aws.EndpointDiscoveryEnabled - case strings.EqualFold(value, endpointDiscoveryAuto): - *dst = aws.EndpointDiscoveryAuto - } -} - -// updateEndpointDiscoveryType will only update the dst with the value in the section, if -// a valid key and corresponding EndpointDiscoveryType is found. -func updateUseDualStackEndpoint(dst *aws.DualStackEndpointState, section ini.Section, key string) { - if !section.Has(key) { - return - } - - // retains pre-#2276 behavior where non-bool value would resolve to false - if v, _ := section.Bool(key); v { - *dst = aws.DualStackEndpointStateEnabled - } else { - *dst = aws.DualStackEndpointStateDisabled - } - - return -} - -// updateEndpointDiscoveryType will only update the dst with the value in the section, if -// a valid key and corresponding EndpointDiscoveryType is found. -func updateUseFIPSEndpoint(dst *aws.FIPSEndpointState, section ini.Section, key string) { - if !section.Has(key) { - return - } - - // retains pre-#2276 behavior where non-bool value would resolve to false - if v, _ := section.Bool(key); v { - *dst = aws.FIPSEndpointStateEnabled - } else { - *dst = aws.FIPSEndpointStateDisabled - } - - return -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md deleted file mode 100644 index 5a0ef6f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md +++ /dev/null @@ -1,719 +0,0 @@ -# v1.17.58 (2025-02-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.57 (2025-01-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.56 (2025-01-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.55 (2025-01-24) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v1.17.54 (2025-01-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.53 (2025-01-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.52 (2025-01-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.51 (2025-01-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.50 (2025-01-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.49 (2025-01-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.48 (2024-12-19) - -* **Bug Fix**: Fix improper use of printf-style functions. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.47 (2024-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.46 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.45 (2024-11-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.44 (2024-11-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.43 (2024-11-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.42 (2024-10-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.41 (2024-10-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.40 (2024-10-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.39 (2024-10-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.38 (2024-10-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.37 (2024-09-27) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.36 (2024-09-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.35 (2024-09-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.34 (2024-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.33 (2024-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.32 (2024-09-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.31 (2024-09-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.30 (2024-08-26) - -* **Bug Fix**: Save SSO cached token expiry in UTC to ensure cross-SDK compatibility. - -# v1.17.29 (2024-08-22) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.28 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.27 (2024-07-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.26 (2024-07-10.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.25 (2024-07-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.24 (2024-07-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.23 (2024-06-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.22 (2024-06-26) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.21 (2024-06-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.20 (2024-06-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.19 (2024-06-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.18 (2024-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.17 (2024-06-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.16 (2024-05-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.15 (2024-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.14 (2024-05-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.13 (2024-05-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.12 (2024-05-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.11 (2024-04-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.10 (2024-03-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.9 (2024-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.8 (2024-03-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.7 (2024-03-07) - -* **Bug Fix**: Remove dependency on go-cmp. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.6 (2024-03-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.5 (2024-03-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.4 (2024-02-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.3 (2024-02-22) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.2 (2024-02-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.1 (2024-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.16 (2024-01-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.15 (2024-01-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.14 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.13 (2023-12-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.12 (2023-12-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.11 (2023-12-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.10 (2023-12-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.9 (2023-12-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.8 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.7 (2023-11-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.6 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.5 (2023-11-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.4 (2023-11-21) - -* **Bug Fix**: Don't expect error responses to have a JSON payload in the endpointcreds provider. - -# v1.16.3 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.2 (2023-11-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.1 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.0 (2023-11-14) - -* **Feature**: Add support for dynamic auth token from file and EKS container host in absolute/relative URIs in the HTTP credential provider. - -# v1.15.2 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.1 (2023-11-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.0 (2023-11-01) - -* **Feature**: Adds support for configured endpoints via environment variables and the AWS shared configuration file. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.43 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.42 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.41 (2023-10-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.40 (2023-09-22) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.39 (2023-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.38 (2023-09-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.37 (2023-09-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.36 (2023-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.35 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.34 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.33 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.32 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.31 (2023-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.30 (2023-07-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.29 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.28 (2023-07-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.27 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.26 (2023-06-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.25 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.24 (2023-05-09) - -* No change notes available for this release. - -# v1.13.23 (2023-05-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.22 (2023-05-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.21 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.20 (2023-04-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.19 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.18 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.17 (2023-03-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.16 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.15 (2023-02-22) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.14 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.13 (2023-02-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.12 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.11 (2023-02-01) - -* No change notes available for this release. - -# v1.13.10 (2023-01-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.9 (2023-01-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.8 (2023-01-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.7 (2022-12-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.6 (2022-12-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.5 (2022-12-15) - -* **Bug Fix**: Unify logic between shared config and in finding home directory -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.4 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.3 (2022-11-22) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.2 (2022-11-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.1 (2022-11-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.0 (2022-11-11) - -* **Announcement**: When using the SSOTokenProvider, a previous implementation incorrectly compensated for invalid SSOTokenProvider configurations in the shared profile. This has been fixed via PR #1903 and tracked in issue #1846 -* **Feature**: Adds token refresh support (via SSOTokenProvider) when using the SSOCredentialProvider - -# v1.12.24 (2022-11-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.23 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.22 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.21 (2022-09-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.20 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.19 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.18 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.17 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.16 (2022-08-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.15 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.14 (2022-08-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.13 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.12 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.11 (2022-08-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.10 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.9 (2022-07-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.8 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.7 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.6 (2022-06-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.5 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.4 (2022-05-26) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.3 (2022-05-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.2 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.1 (2022-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.0 (2022-04-25) - -* **Feature**: Adds Duration and Policy options that can be used when creating stscreds.WebIdentityRoleProvider credentials provider. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.2 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.1 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.0 (2022-03-23) - -* **Feature**: Update `ec2rolecreds` package's `Provider` to implememnt support for CredentialsCache new optional caching strategy interfaces, HandleFailRefreshCredentialsCacheStrategy and AdjustExpiresByCredentialsCacheStrategy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.0 (2022-02-24) - -* **Feature**: Adds support for `SourceIdentity` to `stscreds.AssumeRoleProvider` [#1588](https://github.com/aws/aws-sdk-go-v2/pull/1588). Fixes [#1575](https://github.com/aws/aws-sdk-go-v2/issues/1575) -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.0 (2022-01-14) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.7.0 (2022-01-07) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.5 (2021-12-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.4 (2021-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.3 (2021-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.2 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.1 (2021-11-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.0 (2021-11-06) - -* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.0 (2021-10-21) - -* **Feature**: Updated to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.3 (2021-10-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.2 (2021-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.1 (2021-09-10) - -* **Documentation**: Fixes the AssumeRoleProvider's documentation for using custom TokenProviders. - -# v1.4.0 (2021-08-27) - -* **Feature**: Adds support for Tags and TransitiveTagKeys to stscreds.AssumeRoleProvider. Closes https://github.com/aws/aws-sdk-go-v2/issues/723 -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.3 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.2 (2021-08-04) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.1 (2021-07-15) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.0 (2021-06-25) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Bug Fix**: Fixed example usages of aws.CredentialsCache ([#1275](https://github.com/aws/aws-sdk-go-v2/pull/1275)) -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.1 (2021-05-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.0 (2021-05-14) - -* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting. -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/credentials/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/credentials/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/doc.go deleted file mode 100644 index f6e2873..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -/* -Package credentials provides types for retrieving credentials from credentials sources. -*/ -package credentials diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds/doc.go deleted file mode 100644 index 6ed71b4..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds/doc.go +++ /dev/null @@ -1,58 +0,0 @@ -// Package ec2rolecreds provides the credentials provider implementation for -// retrieving AWS credentials from Amazon EC2 Instance Roles via Amazon EC2 IMDS. -// -// # Concurrency and caching -// -// The Provider is not safe to be used concurrently, and does not provide any -// caching of credentials retrieved. You should wrap the Provider with a -// `aws.CredentialsCache` to provide concurrency safety, and caching of -// credentials. -// -// # Loading credentials with the SDK's AWS Config -// -// The EC2 Instance role credentials provider will automatically be the resolved -// credential provider in the credential chain if no other credential provider is -// resolved first. -// -// To explicitly instruct the SDK's credentials resolving to use the EC2 Instance -// role for credentials, you specify a `credentials_source` property in the config -// profile the SDK will load. -// -// [default] -// credential_source = Ec2InstanceMetadata -// -// # Loading credentials with the Provider directly -// -// Another way to use the EC2 Instance role credentials provider is to create it -// directly and assign it as the credentials provider for an API client. -// -// The following example creates a credentials provider for a command, and wraps -// it with the CredentialsCache before assigning the provider to the Amazon S3 API -// client's Credentials option. -// -// provider := imds.New(imds.Options{}) -// -// // Create the service client value configured for credentials. -// svc := s3.New(s3.Options{ -// Credentials: aws.NewCredentialsCache(provider), -// }) -// -// If you need more control, you can set the configuration options on the -// credentials provider using the imds.Options type to configure the EC2 IMDS -// API Client and ExpiryWindow of the retrieved credentials. -// -// provider := imds.New(imds.Options{ -// // See imds.Options type's documentation for more options available. -// Client: imds.New(Options{ -// HTTPClient: customHTTPClient, -// }), -// -// // Modify how soon credentials expire prior to their original expiry time. -// ExpiryWindow: 5 * time.Minute, -// }) -// -// # EC2 IMDS API Client -// -// See the github.com/aws/aws-sdk-go-v2/feature/ec2/imds module for more details on -// configuring the client, and options available. -package ec2rolecreds diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds/provider.go deleted file mode 100644 index 5c699f1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds/provider.go +++ /dev/null @@ -1,229 +0,0 @@ -package ec2rolecreds - -import ( - "bufio" - "context" - "encoding/json" - "fmt" - "math" - "path" - "strings" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" - sdkrand "github.com/aws/aws-sdk-go-v2/internal/rand" - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/smithy-go" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" -) - -// ProviderName provides a name of EC2Role provider -const ProviderName = "EC2RoleProvider" - -// GetMetadataAPIClient provides the interface for an EC2 IMDS API client for the -// GetMetadata operation. -type GetMetadataAPIClient interface { - GetMetadata(context.Context, *imds.GetMetadataInput, ...func(*imds.Options)) (*imds.GetMetadataOutput, error) -} - -// A Provider retrieves credentials from the EC2 service, and keeps track if -// those credentials are expired. -// -// The New function must be used to create the with a custom EC2 IMDS client. -// -// p := &ec2rolecreds.New(func(o *ec2rolecreds.Options{ -// o.Client = imds.New(imds.Options{/* custom options */}) -// }) -type Provider struct { - options Options -} - -// Options is a list of user settable options for setting the behavior of the Provider. -type Options struct { - // The API client that will be used by the provider to make GetMetadata API - // calls to EC2 IMDS. - // - // If nil, the provider will default to the EC2 IMDS client. - Client GetMetadataAPIClient -} - -// New returns an initialized Provider value configured to retrieve -// credentials from EC2 Instance Metadata service. -func New(optFns ...func(*Options)) *Provider { - options := Options{} - - for _, fn := range optFns { - fn(&options) - } - - if options.Client == nil { - options.Client = imds.New(imds.Options{}) - } - - return &Provider{ - options: options, - } -} - -// Retrieve retrieves credentials from the EC2 service. Error will be returned -// if the request fails, or unable to extract the desired credentials. -func (p *Provider) Retrieve(ctx context.Context) (aws.Credentials, error) { - credsList, err := requestCredList(ctx, p.options.Client) - if err != nil { - return aws.Credentials{Source: ProviderName}, err - } - - if len(credsList) == 0 { - return aws.Credentials{Source: ProviderName}, - fmt.Errorf("unexpected empty EC2 IMDS role list") - } - credsName := credsList[0] - - roleCreds, err := requestCred(ctx, p.options.Client, credsName) - if err != nil { - return aws.Credentials{Source: ProviderName}, err - } - - creds := aws.Credentials{ - AccessKeyID: roleCreds.AccessKeyID, - SecretAccessKey: roleCreds.SecretAccessKey, - SessionToken: roleCreds.Token, - Source: ProviderName, - - CanExpire: true, - Expires: roleCreds.Expiration, - } - - // Cap role credentials Expires to 1 hour so they can be refreshed more - // often. Jitter will be applied credentials cache if being used. - if anHour := sdk.NowTime().Add(1 * time.Hour); creds.Expires.After(anHour) { - creds.Expires = anHour - } - - return creds, nil -} - -// HandleFailToRefresh will extend the credentials Expires time if it it is -// expired. If the credentials will not expire within the minimum time, they -// will be returned. -// -// If the credentials cannot expire, the original error will be returned. -func (p *Provider) HandleFailToRefresh(ctx context.Context, prevCreds aws.Credentials, err error) ( - aws.Credentials, error, -) { - if !prevCreds.CanExpire { - return aws.Credentials{}, err - } - - if prevCreds.Expires.After(sdk.NowTime().Add(5 * time.Minute)) { - return prevCreds, nil - } - - newCreds := prevCreds - randFloat64, err := sdkrand.CryptoRandFloat64() - if err != nil { - return aws.Credentials{}, fmt.Errorf("failed to get random float, %w", err) - } - - // Random distribution of [5,15) minutes. - expireOffset := time.Duration(randFloat64*float64(10*time.Minute)) + 5*time.Minute - newCreds.Expires = sdk.NowTime().Add(expireOffset) - - logger := middleware.GetLogger(ctx) - logger.Logf(logging.Warn, "Attempting credential expiration extension due to a credential service availability issue. A refresh of these credentials will be attempted again in %v minutes.", math.Floor(expireOffset.Minutes())) - - return newCreds, nil -} - -// AdjustExpiresBy will adds the passed in duration to the passed in -// credential's Expires time, unless the time until Expires is less than 15 -// minutes. Returns the credentials, even if not updated. -func (p *Provider) AdjustExpiresBy(creds aws.Credentials, dur time.Duration) ( - aws.Credentials, error, -) { - if !creds.CanExpire { - return creds, nil - } - if creds.Expires.Before(sdk.NowTime().Add(15 * time.Minute)) { - return creds, nil - } - - creds.Expires = creds.Expires.Add(dur) - return creds, nil -} - -// ec2RoleCredRespBody provides the shape for unmarshaling credential -// request responses. -type ec2RoleCredRespBody struct { - // Success State - Expiration time.Time - AccessKeyID string - SecretAccessKey string - Token string - - // Error state - Code string - Message string -} - -const iamSecurityCredsPath = "/iam/security-credentials/" - -// requestCredList requests a list of credentials from the EC2 service. If -// there are no credentials, or there is an error making or receiving the -// request -func requestCredList(ctx context.Context, client GetMetadataAPIClient) ([]string, error) { - resp, err := client.GetMetadata(ctx, &imds.GetMetadataInput{ - Path: iamSecurityCredsPath, - }) - if err != nil { - return nil, fmt.Errorf("no EC2 IMDS role found, %w", err) - } - defer resp.Content.Close() - - credsList := []string{} - s := bufio.NewScanner(resp.Content) - for s.Scan() { - credsList = append(credsList, s.Text()) - } - - if err := s.Err(); err != nil { - return nil, fmt.Errorf("failed to read EC2 IMDS role, %w", err) - } - - return credsList, nil -} - -// requestCred requests the credentials for a specific credentials from the EC2 service. -// -// If the credentials cannot be found, or there is an error reading the response -// and error will be returned. -func requestCred(ctx context.Context, client GetMetadataAPIClient, credsName string) (ec2RoleCredRespBody, error) { - resp, err := client.GetMetadata(ctx, &imds.GetMetadataInput{ - Path: path.Join(iamSecurityCredsPath, credsName), - }) - if err != nil { - return ec2RoleCredRespBody{}, - fmt.Errorf("failed to get %s EC2 IMDS role credentials, %w", - credsName, err) - } - defer resp.Content.Close() - - var respCreds ec2RoleCredRespBody - if err := json.NewDecoder(resp.Content).Decode(&respCreds); err != nil { - return ec2RoleCredRespBody{}, - fmt.Errorf("failed to decode %s EC2 IMDS role credentials, %w", - credsName, err) - } - - if !strings.EqualFold(respCreds.Code, "Success") { - // If an error code was returned something failed requesting the role. - return ec2RoleCredRespBody{}, - fmt.Errorf("failed to get %s EC2 IMDS role credentials, %w", - credsName, - &smithy.GenericAPIError{Code: respCreds.Code, Message: respCreds.Message}) - } - - return respCreds, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/auth.go deleted file mode 100644 index c3f5dad..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/auth.go +++ /dev/null @@ -1,48 +0,0 @@ -package client - -import ( - "context" - "github.com/aws/smithy-go/middleware" -) - -type getIdentityMiddleware struct { - options Options -} - -func (*getIdentityMiddleware) ID() string { - return "GetIdentity" -} - -func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - return next.HandleFinalize(ctx, in) -} - -type signRequestMiddleware struct { -} - -func (*signRequestMiddleware) ID() string { - return "Signing" -} - -func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - return next.HandleFinalize(ctx, in) -} - -type resolveAuthSchemeMiddleware struct { - operation string - options Options -} - -func (*resolveAuthSchemeMiddleware) ID() string { - return "ResolveAuthScheme" -} - -func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go deleted file mode 100644 index dc291c9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go +++ /dev/null @@ -1,165 +0,0 @@ -package client - -import ( - "context" - "fmt" - "net/http" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/retry" - awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" - "github.com/aws/smithy-go" - smithymiddleware "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// ServiceID is the client identifer -const ServiceID = "endpoint-credentials" - -// HTTPClient is a client for sending HTTP requests -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) -} - -// Options is the endpoint client configurable options -type Options struct { - // The endpoint to retrieve credentials from - Endpoint string - - // The HTTP client to invoke API calls with. Defaults to client's default HTTP - // implementation if nil. - HTTPClient HTTPClient - - // Retryer guides how HTTP requests should be retried in case of recoverable - // failures. When nil the API client will use a default retryer. - Retryer aws.Retryer - - // Set of options to modify how the credentials operation is invoked. - APIOptions []func(*smithymiddleware.Stack) error -} - -// Copy creates a copy of the API options. -func (o Options) Copy() Options { - to := o - to.APIOptions = make([]func(*smithymiddleware.Stack) error, len(o.APIOptions)) - copy(to.APIOptions, o.APIOptions) - return to -} - -// Client is an client for retrieving AWS credentials from an endpoint -type Client struct { - options Options -} - -// New constructs a new Client from the given options -func New(options Options, optFns ...func(*Options)) *Client { - options = options.Copy() - - if options.HTTPClient == nil { - options.HTTPClient = awshttp.NewBuildableClient() - } - - if options.Retryer == nil { - // Amazon-owned implementations of this endpoint are known to sometimes - // return plaintext responses (i.e. no Code) like normal, add a few - // additional status codes - options.Retryer = retry.NewStandard(func(o *retry.StandardOptions) { - o.Retryables = append(o.Retryables, retry.RetryableHTTPStatusCode{ - Codes: map[int]struct{}{ - http.StatusTooManyRequests: {}, - }, - }) - }) - } - - for _, fn := range optFns { - fn(&options) - } - - client := &Client{ - options: options, - } - - return client -} - -// GetCredentialsInput is the input to send with the endpoint service to receive credentials. -type GetCredentialsInput struct { - AuthorizationToken string -} - -// GetCredentials retrieves credentials from credential endpoint -func (c *Client) GetCredentials(ctx context.Context, params *GetCredentialsInput, optFns ...func(*Options)) (*GetCredentialsOutput, error) { - stack := smithymiddleware.NewStack("GetCredentials", smithyhttp.NewStackRequest) - options := c.options.Copy() - for _, fn := range optFns { - fn(&options) - } - - stack.Serialize.Add(&serializeOpGetCredential{}, smithymiddleware.After) - stack.Build.Add(&buildEndpoint{Endpoint: options.Endpoint}, smithymiddleware.After) - stack.Deserialize.Add(&deserializeOpGetCredential{}, smithymiddleware.After) - addProtocolFinalizerMiddlewares(stack, options, "GetCredentials") - retry.AddRetryMiddlewares(stack, retry.AddRetryMiddlewaresOptions{Retryer: options.Retryer}) - middleware.AddSDKAgentKey(middleware.FeatureMetadata, ServiceID) - smithyhttp.AddErrorCloseResponseBodyMiddleware(stack) - smithyhttp.AddCloseResponseBodyMiddleware(stack) - - for _, fn := range options.APIOptions { - if err := fn(stack); err != nil { - return nil, err - } - } - - handler := smithymiddleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack) - result, _, err := handler.Handle(ctx, params) - if err != nil { - return nil, err - } - - return result.(*GetCredentialsOutput), err -} - -// GetCredentialsOutput is the response from the credential endpoint -type GetCredentialsOutput struct { - Expiration *time.Time - AccessKeyID string - SecretAccessKey string - Token string - AccountID string -} - -// EndpointError is an error returned from the endpoint service -type EndpointError struct { - Code string `json:"code"` - Message string `json:"message"` - Fault smithy.ErrorFault `json:"-"` - statusCode int `json:"-"` -} - -// Error is the error mesage string -func (e *EndpointError) Error() string { - return fmt.Sprintf("%s: %s", e.Code, e.Message) -} - -// ErrorCode is the error code returned by the endpoint -func (e *EndpointError) ErrorCode() string { - return e.Code -} - -// ErrorMessage is the error message returned by the endpoint -func (e *EndpointError) ErrorMessage() string { - return e.Message -} - -// ErrorFault indicates error fault classification -func (e *EndpointError) ErrorFault() smithy.ErrorFault { - return e.Fault -} - -// HTTPStatusCode implements retry.HTTPStatusCode. -func (e *EndpointError) HTTPStatusCode() int { - return e.statusCode -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/endpoints.go deleted file mode 100644 index 748ee67..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/endpoints.go +++ /dev/null @@ -1,20 +0,0 @@ -package client - -import ( - "context" - "github.com/aws/smithy-go/middleware" -) - -type resolveEndpointV2Middleware struct { - options Options -} - -func (*resolveEndpointV2Middleware) ID() string { - return "ResolveEndpointV2" -} - -func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go deleted file mode 100644 index f2820d2..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go +++ /dev/null @@ -1,164 +0,0 @@ -package client - -import ( - "context" - "encoding/json" - "fmt" - "io" - "net/url" - - "github.com/aws/smithy-go" - smithymiddleware "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -type buildEndpoint struct { - Endpoint string -} - -func (b *buildEndpoint) ID() string { - return "BuildEndpoint" -} - -func (b *buildEndpoint) HandleBuild(ctx context.Context, in smithymiddleware.BuildInput, next smithymiddleware.BuildHandler) ( - out smithymiddleware.BuildOutput, metadata smithymiddleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport, %T", in.Request) - } - - if len(b.Endpoint) == 0 { - return out, metadata, fmt.Errorf("endpoint not provided") - } - - parsed, err := url.Parse(b.Endpoint) - if err != nil { - return out, metadata, fmt.Errorf("failed to parse endpoint, %w", err) - } - - request.URL = parsed - - return next.HandleBuild(ctx, in) -} - -type serializeOpGetCredential struct{} - -func (s *serializeOpGetCredential) ID() string { - return "OperationSerializer" -} - -func (s *serializeOpGetCredential) HandleSerialize(ctx context.Context, in smithymiddleware.SerializeInput, next smithymiddleware.SerializeHandler) ( - out smithymiddleware.SerializeOutput, metadata smithymiddleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type, %T", in.Request) - } - - params, ok := in.Parameters.(*GetCredentialsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters, %T", in.Parameters) - } - - const acceptHeader = "Accept" - request.Header[acceptHeader] = append(request.Header[acceptHeader][:0], "application/json") - - if len(params.AuthorizationToken) > 0 { - const authHeader = "Authorization" - request.Header[authHeader] = append(request.Header[authHeader][:0], params.AuthorizationToken) - } - - return next.HandleSerialize(ctx, in) -} - -type deserializeOpGetCredential struct{} - -func (d *deserializeOpGetCredential) ID() string { - return "OperationDeserializer" -} - -func (d *deserializeOpGetCredential) HandleDeserialize(ctx context.Context, in smithymiddleware.DeserializeInput, next smithymiddleware.DeserializeHandler) ( - out smithymiddleware.DeserializeOutput, metadata smithymiddleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, deserializeError(response) - } - - var shape *GetCredentialsOutput - if err = json.NewDecoder(response.Body).Decode(&shape); err != nil { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("failed to deserialize json response, %w", err)} - } - - out.Result = shape - return out, metadata, err -} - -func deserializeError(response *smithyhttp.Response) error { - // we could be talking to anything, json isn't guaranteed - // see https://github.com/aws/aws-sdk-go-v2/issues/2316 - if response.Header.Get("Content-Type") == "application/json" { - return deserializeJSONError(response) - } - - msg, err := io.ReadAll(response.Body) - if err != nil { - return &smithy.DeserializationError{ - Err: fmt.Errorf("read response, %w", err), - } - } - - return &EndpointError{ - // no sensible value for Code - Message: string(msg), - Fault: stof(response.StatusCode), - statusCode: response.StatusCode, - } -} - -func deserializeJSONError(response *smithyhttp.Response) error { - var errShape *EndpointError - if err := json.NewDecoder(response.Body).Decode(&errShape); err != nil { - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode error message, %w", err), - } - } - - errShape.Fault = stof(response.StatusCode) - errShape.statusCode = response.StatusCode - return errShape -} - -// maps HTTP status code to smithy ErrorFault -func stof(code int) smithy.ErrorFault { - if code >= 500 { - return smithy.FaultServer - } - return smithy.FaultClient -} - -func addProtocolFinalizerMiddlewares(stack *smithymiddleware.Stack, options Options, operation string) error { - if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, smithymiddleware.Before); err != nil { - return fmt.Errorf("add ResolveAuthScheme: %w", err) - } - if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", smithymiddleware.After); err != nil { - return fmt.Errorf("add GetIdentity: %w", err) - } - if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", smithymiddleware.After); err != nil { - return fmt.Errorf("add ResolveEndpointV2: %w", err) - } - if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", smithymiddleware.After); err != nil { - return fmt.Errorf("add Signing: %w", err) - } - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider.go deleted file mode 100644 index 2386153..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider.go +++ /dev/null @@ -1,193 +0,0 @@ -// Package endpointcreds provides support for retrieving credentials from an -// arbitrary HTTP endpoint. -// -// The credentials endpoint Provider can receive both static and refreshable -// credentials that will expire. Credentials are static when an "Expiration" -// value is not provided in the endpoint's response. -// -// Static credentials will never expire once they have been retrieved. The format -// of the static credentials response: -// -// { -// "AccessKeyId" : "MUA...", -// "SecretAccessKey" : "/7PC5om....", -// } -// -// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration -// value in the response. The format of the refreshable credentials response: -// -// { -// "AccessKeyId" : "MUA...", -// "SecretAccessKey" : "/7PC5om....", -// "Token" : "AQoDY....=", -// "Expiration" : "2016-02-25T06:03:31Z" -// } -// -// Errors should be returned in the following format and only returned with 400 -// or 500 HTTP status codes. -// -// { -// "code": "ErrorCode", -// "message": "Helpful error message." -// } -package endpointcreds - -import ( - "context" - "fmt" - "net/http" - "strings" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client" - "github.com/aws/smithy-go/middleware" -) - -// ProviderName is the name of the credentials provider. -const ProviderName = `CredentialsEndpointProvider` - -type getCredentialsAPIClient interface { - GetCredentials(context.Context, *client.GetCredentialsInput, ...func(*client.Options)) (*client.GetCredentialsOutput, error) -} - -// Provider satisfies the aws.CredentialsProvider interface, and is a client to -// retrieve credentials from an arbitrary endpoint. -type Provider struct { - // The AWS Client to make HTTP requests to the endpoint with. The endpoint - // the request will be made to is provided by the aws.Config's - // EndpointResolver. - client getCredentialsAPIClient - - options Options -} - -// HTTPClient is a client for sending HTTP requests -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) -} - -// Options is structure of configurable options for Provider -type Options struct { - // Endpoint to retrieve credentials from. Required - Endpoint string - - // HTTPClient to handle sending HTTP requests to the target endpoint. - HTTPClient HTTPClient - - // Set of options to modify how the credentials operation is invoked. - APIOptions []func(*middleware.Stack) error - - // The Retryer to be used for determining whether a failed requested should be retried - Retryer aws.Retryer - - // Optional authorization token value if set will be used as the value of - // the Authorization header of the endpoint credential request. - // - // When constructed from environment, the provider will use the value of - // AWS_CONTAINER_AUTHORIZATION_TOKEN environment variable as the token - // - // Will be overridden if AuthorizationTokenProvider is configured - AuthorizationToken string - - // Optional auth provider func to dynamically load the auth token from a file - // everytime a credential is retrieved - // - // When constructed from environment, the provider will read and use the content - // of the file pointed to by AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE environment variable - // as the auth token everytime credentials are retrieved - // - // Will override AuthorizationToken if configured - AuthorizationTokenProvider AuthTokenProvider -} - -// AuthTokenProvider defines an interface to dynamically load a value to be passed -// for the Authorization header of a credentials request. -type AuthTokenProvider interface { - GetToken() (string, error) -} - -// TokenProviderFunc is a func type implementing AuthTokenProvider interface -// and enables customizing token provider behavior -type TokenProviderFunc func() (string, error) - -// GetToken func retrieves auth token according to TokenProviderFunc implementation -func (p TokenProviderFunc) GetToken() (string, error) { - return p() -} - -// New returns a credentials Provider for retrieving AWS credentials -// from arbitrary endpoint. -func New(endpoint string, optFns ...func(*Options)) *Provider { - o := Options{ - Endpoint: endpoint, - } - - for _, fn := range optFns { - fn(&o) - } - - p := &Provider{ - client: client.New(client.Options{ - HTTPClient: o.HTTPClient, - Endpoint: o.Endpoint, - APIOptions: o.APIOptions, - Retryer: o.Retryer, - }), - options: o, - } - - return p -} - -// Retrieve will attempt to request the credentials from the endpoint the Provider -// was configured for. And error will be returned if the retrieval fails. -func (p *Provider) Retrieve(ctx context.Context) (aws.Credentials, error) { - resp, err := p.getCredentials(ctx) - if err != nil { - return aws.Credentials{}, fmt.Errorf("failed to load credentials, %w", err) - } - - creds := aws.Credentials{ - AccessKeyID: resp.AccessKeyID, - SecretAccessKey: resp.SecretAccessKey, - SessionToken: resp.Token, - Source: ProviderName, - AccountID: resp.AccountID, - } - - if resp.Expiration != nil { - creds.CanExpire = true - creds.Expires = *resp.Expiration - } - - return creds, nil -} - -func (p *Provider) getCredentials(ctx context.Context) (*client.GetCredentialsOutput, error) { - authToken, err := p.resolveAuthToken() - if err != nil { - return nil, fmt.Errorf("resolve auth token: %v", err) - } - - return p.client.GetCredentials(ctx, &client.GetCredentialsInput{ - AuthorizationToken: authToken, - }) -} - -func (p *Provider) resolveAuthToken() (string, error) { - authToken := p.options.AuthorizationToken - - var err error - if p.options.AuthorizationTokenProvider != nil { - authToken, err = p.options.AuthorizationTokenProvider.GetToken() - if err != nil { - return "", err - } - } - - if strings.ContainsAny(authToken, "\r\n") { - return "", fmt.Errorf("authorization token contains invalid newline sequence") - } - - return authToken, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go deleted file mode 100644 index 20eaebc..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package credentials - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.17.58" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/processcreds/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/processcreds/doc.go deleted file mode 100644 index a3137b8..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/processcreds/doc.go +++ /dev/null @@ -1,92 +0,0 @@ -// Package processcreds is a credentials provider to retrieve credentials from a -// external CLI invoked process. -// -// WARNING: The following describes a method of sourcing credentials from an external -// process. This can potentially be dangerous, so proceed with caution. Other -// credential providers should be preferred if at all possible. If using this -// option, you should make sure that the config file is as locked down as possible -// using security best practices for your operating system. -// -// # Concurrency and caching -// -// The Provider is not safe to be used concurrently, and does not provide any -// caching of credentials retrieved. You should wrap the Provider with a -// `aws.CredentialsCache` to provide concurrency safety, and caching of -// credentials. -// -// # Loading credentials with the SDKs AWS Config -// -// You can use credentials from a AWS shared config `credential_process` in a -// variety of ways. -// -// One way is to setup your shared config file, located in the default -// location, with the `credential_process` key and the command you want to be -// called. You also need to set the AWS_SDK_LOAD_CONFIG environment variable -// (e.g., `export AWS_SDK_LOAD_CONFIG=1`) to use the shared config file. -// -// [default] -// credential_process = /command/to/call -// -// Loading configuration using external will use the credential process to -// retrieve credentials. NOTE: If there are credentials in the profile you are -// using, the credential process will not be used. -// -// // Initialize a session to load credentials. -// cfg, _ := config.LoadDefaultConfig(context.TODO()) -// -// // Create S3 service client to use the credentials. -// svc := s3.NewFromConfig(cfg) -// -// # Loading credentials with the Provider directly -// -// Another way to use the credentials process provider is by using the -// `NewProvider` constructor to create the provider and providing a it with a -// command to be executed to retrieve credentials. -// -// The following example creates a credentials provider for a command, and wraps -// it with the CredentialsCache before assigning the provider to the Amazon S3 API -// client's Credentials option. -// -// // Create credentials using the Provider. -// provider := processcreds.NewProvider("/path/to/command") -// -// // Create the service client value configured for credentials. -// svc := s3.New(s3.Options{ -// Credentials: aws.NewCredentialsCache(provider), -// }) -// -// If you need more control, you can set any configurable options in the -// credentials using one or more option functions. -// -// provider := processcreds.NewProvider("/path/to/command", -// func(o *processcreds.Options) { -// // Override the provider's default timeout -// o.Timeout = 2 * time.Minute -// }) -// -// You can also use your own `exec.Cmd` value by satisfying a value that satisfies -// the `NewCommandBuilder` interface and use the `NewProviderCommand` constructor. -// -// // Create an exec.Cmd -// cmdBuilder := processcreds.NewCommandBuilderFunc( -// func(ctx context.Context) (*exec.Cmd, error) { -// cmd := exec.CommandContext(ctx, -// "customCLICommand", -// "-a", "argument", -// ) -// cmd.Env = []string{ -// "ENV_VAR_FOO=value", -// "ENV_VAR_BAR=other_value", -// } -// -// return cmd, nil -// }, -// ) -// -// // Create credentials using your exec.Cmd and custom timeout -// provider := processcreds.NewProviderCommand(cmdBuilder, -// func(opt *processcreds.Provider) { -// // optionally override the provider's default timeout -// opt.Timeout = 1 * time.Second -// }) -package processcreds diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/processcreds/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/processcreds/provider.go deleted file mode 100644 index 911fcc3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/processcreds/provider.go +++ /dev/null @@ -1,285 +0,0 @@ -package processcreds - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "os" - "os/exec" - "runtime" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/internal/sdkio" -) - -const ( - // ProviderName is the name this credentials provider will label any - // returned credentials Value with. - ProviderName = `ProcessProvider` - - // DefaultTimeout default limit on time a process can run. - DefaultTimeout = time.Duration(1) * time.Minute -) - -// ProviderError is an error indicating failure initializing or executing the -// process credentials provider -type ProviderError struct { - Err error -} - -// Error returns the error message. -func (e *ProviderError) Error() string { - return fmt.Sprintf("process provider error: %v", e.Err) -} - -// Unwrap returns the underlying error the provider error wraps. -func (e *ProviderError) Unwrap() error { - return e.Err -} - -// Provider satisfies the credentials.Provider interface, and is a -// client to retrieve credentials from a process. -type Provider struct { - // Provides a constructor for exec.Cmd that are invoked by the provider for - // retrieving credentials. Use this to provide custom creation of exec.Cmd - // with things like environment variables, or other configuration. - // - // The provider defaults to the DefaultNewCommand function. - commandBuilder NewCommandBuilder - - options Options -} - -// Options is the configuration options for configuring the Provider. -type Options struct { - // Timeout limits the time a process can run. - Timeout time.Duration -} - -// NewCommandBuilder provides the interface for specifying how command will be -// created that the Provider will use to retrieve credentials with. -type NewCommandBuilder interface { - NewCommand(context.Context) (*exec.Cmd, error) -} - -// NewCommandBuilderFunc provides a wrapper type around a function pointer to -// satisfy the NewCommandBuilder interface. -type NewCommandBuilderFunc func(context.Context) (*exec.Cmd, error) - -// NewCommand calls the underlying function pointer the builder was initialized with. -func (fn NewCommandBuilderFunc) NewCommand(ctx context.Context) (*exec.Cmd, error) { - return fn(ctx) -} - -// DefaultNewCommandBuilder provides the default NewCommandBuilder -// implementation used by the provider. It takes a command and arguments to -// invoke. The command will also be initialized with the current process -// environment variables, stderr, and stdin pipes. -type DefaultNewCommandBuilder struct { - Args []string -} - -// NewCommand returns an initialized exec.Cmd with the builder's initialized -// Args. The command is also initialized current process environment variables, -// stderr, and stdin pipes. -func (b DefaultNewCommandBuilder) NewCommand(ctx context.Context) (*exec.Cmd, error) { - var cmdArgs []string - if runtime.GOOS == "windows" { - cmdArgs = []string{"cmd.exe", "/C"} - } else { - cmdArgs = []string{"sh", "-c"} - } - - if len(b.Args) == 0 { - return nil, &ProviderError{ - Err: fmt.Errorf("failed to prepare command: command must not be empty"), - } - } - - cmdArgs = append(cmdArgs, b.Args...) - cmd := exec.CommandContext(ctx, cmdArgs[0], cmdArgs[1:]...) - cmd.Env = os.Environ() - - cmd.Stderr = os.Stderr // display stderr on console for MFA - cmd.Stdin = os.Stdin // enable stdin for MFA - - return cmd, nil -} - -// NewProvider returns a pointer to a new Credentials object wrapping the -// Provider. -// -// The provider defaults to the DefaultNewCommandBuilder for creating command -// the Provider will use to retrieve credentials with. -func NewProvider(command string, options ...func(*Options)) *Provider { - var args []string - - // Ensure that the command arguments are not set if the provided command is - // empty. This will error out when the command is executed since no - // arguments are specified. - if len(command) > 0 { - args = []string{command} - } - - commanBuilder := DefaultNewCommandBuilder{ - Args: args, - } - return NewProviderCommand(commanBuilder, options...) -} - -// NewProviderCommand returns a pointer to a new Credentials object with the -// specified command, and default timeout duration. Use this to provide custom -// creation of exec.Cmd for options like environment variables, or other -// configuration. -func NewProviderCommand(builder NewCommandBuilder, options ...func(*Options)) *Provider { - p := &Provider{ - commandBuilder: builder, - options: Options{ - Timeout: DefaultTimeout, - }, - } - - for _, option := range options { - option(&p.options) - } - - return p -} - -// A CredentialProcessResponse is the AWS credentials format that must be -// returned when executing an external credential_process. -type CredentialProcessResponse struct { - // As of this writing, the Version key must be set to 1. This might - // increment over time as the structure evolves. - Version int - - // The access key ID that identifies the temporary security credentials. - AccessKeyID string `json:"AccessKeyId"` - - // The secret access key that can be used to sign requests. - SecretAccessKey string - - // The token that users must pass to the service API to use the temporary credentials. - SessionToken string - - // The date on which the current credentials expire. - Expiration *time.Time - - // The ID of the account for credentials - AccountID string `json:"AccountId"` -} - -// Retrieve executes the credential process command and returns the -// credentials, or error if the command fails. -func (p *Provider) Retrieve(ctx context.Context) (aws.Credentials, error) { - out, err := p.executeCredentialProcess(ctx) - if err != nil { - return aws.Credentials{Source: ProviderName}, err - } - - // Serialize and validate response - resp := &CredentialProcessResponse{} - if err = json.Unmarshal(out, resp); err != nil { - return aws.Credentials{Source: ProviderName}, &ProviderError{ - Err: fmt.Errorf("parse failed of process output: %s, error: %w", out, err), - } - } - - if resp.Version != 1 { - return aws.Credentials{Source: ProviderName}, &ProviderError{ - Err: fmt.Errorf("wrong version in process output (not 1)"), - } - } - - if len(resp.AccessKeyID) == 0 { - return aws.Credentials{Source: ProviderName}, &ProviderError{ - Err: fmt.Errorf("missing AccessKeyId in process output"), - } - } - - if len(resp.SecretAccessKey) == 0 { - return aws.Credentials{Source: ProviderName}, &ProviderError{ - Err: fmt.Errorf("missing SecretAccessKey in process output"), - } - } - - creds := aws.Credentials{ - Source: ProviderName, - AccessKeyID: resp.AccessKeyID, - SecretAccessKey: resp.SecretAccessKey, - SessionToken: resp.SessionToken, - AccountID: resp.AccountID, - } - - // Handle expiration - if resp.Expiration != nil { - creds.CanExpire = true - creds.Expires = *resp.Expiration - } - - return creds, nil -} - -// executeCredentialProcess starts the credential process on the OS and -// returns the results or an error. -func (p *Provider) executeCredentialProcess(ctx context.Context) ([]byte, error) { - if p.options.Timeout >= 0 { - var cancelFunc func() - ctx, cancelFunc = context.WithTimeout(ctx, p.options.Timeout) - defer cancelFunc() - } - - cmd, err := p.commandBuilder.NewCommand(ctx) - if err != nil { - return nil, err - } - - // get creds json on process's stdout - output := bytes.NewBuffer(make([]byte, 0, int(8*sdkio.KibiByte))) - if cmd.Stdout != nil { - cmd.Stdout = io.MultiWriter(cmd.Stdout, output) - } else { - cmd.Stdout = output - } - - execCh := make(chan error, 1) - go executeCommand(cmd, execCh) - - select { - case execError := <-execCh: - if execError == nil { - break - } - select { - case <-ctx.Done(): - return output.Bytes(), &ProviderError{ - Err: fmt.Errorf("credential process timed out: %w", execError), - } - default: - return output.Bytes(), &ProviderError{ - Err: fmt.Errorf("error in credential_process: %w", execError), - } - } - } - - out := output.Bytes() - if runtime.GOOS == "windows" { - // windows adds slashes to quotes - out = bytes.ReplaceAll(out, []byte(`\"`), []byte(`"`)) - } - - return out, nil -} - -func executeCommand(cmd *exec.Cmd, exec chan error) { - // Start the command - err := cmd.Start() - if err == nil { - err = cmd.Wait() - } - - exec <- err -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/doc.go deleted file mode 100644 index ece1e65..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/doc.go +++ /dev/null @@ -1,81 +0,0 @@ -// Package ssocreds provides a credential provider for retrieving temporary AWS -// credentials using an SSO access token. -// -// IMPORTANT: The provider in this package does not initiate or perform the AWS -// SSO login flow. The SDK provider expects that you have already performed the -// SSO login flow using AWS CLI using the "aws sso login" command, or by some -// other mechanism. The provider must find a valid non-expired access token for -// the AWS SSO user portal URL in ~/.aws/sso/cache. If a cached token is not -// found, it is expired, or the file is malformed an error will be returned. -// -// # Loading AWS SSO credentials with the AWS shared configuration file -// -// You can use configure AWS SSO credentials from the AWS shared configuration file by -// specifying the required keys in the profile and referencing an sso-session: -// -// sso_session -// sso_account_id -// sso_role_name -// -// For example, the following defines a profile "devsso" and specifies the AWS -// SSO parameters that defines the target account, role, sign-on portal, and -// the region where the user portal is located. Note: all SSO arguments must be -// provided, or an error will be returned. -// -// [profile devsso] -// sso_session = dev-session -// sso_role_name = SSOReadOnlyRole -// sso_account_id = 123456789012 -// -// [sso-session dev-session] -// sso_start_url = https://my-sso-portal.awsapps.com/start -// sso_region = us-east-1 -// sso_registration_scopes = sso:account:access -// -// Using the config module, you can load the AWS SDK shared configuration, and -// specify that this profile be used to retrieve credentials. For example: -// -// config, err := config.LoadDefaultConfig(context.TODO(), config.WithSharedConfigProfile("devsso")) -// if err != nil { -// return err -// } -// -// # Programmatically loading AWS SSO credentials directly -// -// You can programmatically construct the AWS SSO Provider in your application, -// and provide the necessary information to load and retrieve temporary -// credentials using an access token from ~/.aws/sso/cache. -// -// ssoClient := sso.NewFromConfig(cfg) -// ssoOidcClient := ssooidc.NewFromConfig(cfg) -// tokenPath, err := ssocreds.StandardCachedTokenFilepath("dev-session") -// if err != nil { -// return err -// } -// -// var provider aws.CredentialsProvider -// provider = ssocreds.New(ssoClient, "123456789012", "SSOReadOnlyRole", "https://my-sso-portal.awsapps.com/start", func(options *ssocreds.Options) { -// options.SSOTokenProvider = ssocreds.NewSSOTokenProvider(ssoOidcClient, tokenPath) -// }) -// -// // Wrap the provider with aws.CredentialsCache to cache the credentials until their expire time -// provider = aws.NewCredentialsCache(provider) -// -// credentials, err := provider.Retrieve(context.TODO()) -// if err != nil { -// return err -// } -// -// It is important that you wrap the Provider with aws.CredentialsCache if you -// are programmatically constructing the provider directly. This prevents your -// application from accessing the cached access token and requesting new -// credentials each time the credentials are used. -// -// # Additional Resources -// -// Configuring the AWS CLI to use AWS Single Sign-On: -// https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html -// -// AWS Single Sign-On User Guide: -// https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html -package ssocreds diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_cached_token.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_cached_token.go deleted file mode 100644 index 46ae2f9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_cached_token.go +++ /dev/null @@ -1,233 +0,0 @@ -package ssocreds - -import ( - "crypto/sha1" - "encoding/hex" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/aws-sdk-go-v2/internal/shareddefaults" -) - -var osUserHomeDur = shareddefaults.UserHomeDir - -// StandardCachedTokenFilepath returns the filepath for the cached SSO token file, or -// error if unable get derive the path. Key that will be used to compute a SHA1 -// value that is hex encoded. -// -// Derives the filepath using the Key as: -// -// ~/.aws/sso/cache/.json -func StandardCachedTokenFilepath(key string) (string, error) { - homeDir := osUserHomeDur() - if len(homeDir) == 0 { - return "", fmt.Errorf("unable to get USER's home directory for cached token") - } - hash := sha1.New() - if _, err := hash.Write([]byte(key)); err != nil { - return "", fmt.Errorf("unable to compute cached token filepath key SHA1 hash, %w", err) - } - - cacheFilename := strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json" - - return filepath.Join(homeDir, ".aws", "sso", "cache", cacheFilename), nil -} - -type tokenKnownFields struct { - AccessToken string `json:"accessToken,omitempty"` - ExpiresAt *rfc3339 `json:"expiresAt,omitempty"` - - RefreshToken string `json:"refreshToken,omitempty"` - ClientID string `json:"clientId,omitempty"` - ClientSecret string `json:"clientSecret,omitempty"` -} - -type token struct { - tokenKnownFields - UnknownFields map[string]interface{} `json:"-"` -} - -func (t token) MarshalJSON() ([]byte, error) { - fields := map[string]interface{}{} - - setTokenFieldString(fields, "accessToken", t.AccessToken) - setTokenFieldRFC3339(fields, "expiresAt", t.ExpiresAt) - - setTokenFieldString(fields, "refreshToken", t.RefreshToken) - setTokenFieldString(fields, "clientId", t.ClientID) - setTokenFieldString(fields, "clientSecret", t.ClientSecret) - - for k, v := range t.UnknownFields { - if _, ok := fields[k]; ok { - return nil, fmt.Errorf("unknown token field %v, duplicates known field", k) - } - fields[k] = v - } - - return json.Marshal(fields) -} - -func setTokenFieldString(fields map[string]interface{}, key, value string) { - if value == "" { - return - } - fields[key] = value -} -func setTokenFieldRFC3339(fields map[string]interface{}, key string, value *rfc3339) { - if value == nil { - return - } - fields[key] = value -} - -func (t *token) UnmarshalJSON(b []byte) error { - var fields map[string]interface{} - if err := json.Unmarshal(b, &fields); err != nil { - return nil - } - - t.UnknownFields = map[string]interface{}{} - - for k, v := range fields { - var err error - switch k { - case "accessToken": - err = getTokenFieldString(v, &t.AccessToken) - case "expiresAt": - err = getTokenFieldRFC3339(v, &t.ExpiresAt) - case "refreshToken": - err = getTokenFieldString(v, &t.RefreshToken) - case "clientId": - err = getTokenFieldString(v, &t.ClientID) - case "clientSecret": - err = getTokenFieldString(v, &t.ClientSecret) - default: - t.UnknownFields[k] = v - } - - if err != nil { - return fmt.Errorf("field %q, %w", k, err) - } - } - - return nil -} - -func getTokenFieldString(v interface{}, value *string) error { - var ok bool - *value, ok = v.(string) - if !ok { - return fmt.Errorf("expect value to be string, got %T", v) - } - return nil -} - -func getTokenFieldRFC3339(v interface{}, value **rfc3339) error { - var stringValue string - if err := getTokenFieldString(v, &stringValue); err != nil { - return err - } - - timeValue, err := parseRFC3339(stringValue) - if err != nil { - return err - } - - *value = &timeValue - return nil -} - -func loadCachedToken(filename string) (token, error) { - fileBytes, err := ioutil.ReadFile(filename) - if err != nil { - return token{}, fmt.Errorf("failed to read cached SSO token file, %w", err) - } - - var t token - if err := json.Unmarshal(fileBytes, &t); err != nil { - return token{}, fmt.Errorf("failed to parse cached SSO token file, %w", err) - } - - if len(t.AccessToken) == 0 || t.ExpiresAt == nil || time.Time(*t.ExpiresAt).IsZero() { - return token{}, fmt.Errorf( - "cached SSO token must contain accessToken and expiresAt fields") - } - - return t, nil -} - -func storeCachedToken(filename string, t token, fileMode os.FileMode) (err error) { - tmpFilename := filename + ".tmp-" + strconv.FormatInt(sdk.NowTime().UnixNano(), 10) - if err := writeCacheFile(tmpFilename, fileMode, t); err != nil { - return err - } - - if err := os.Rename(tmpFilename, filename); err != nil { - return fmt.Errorf("failed to replace old cached SSO token file, %w", err) - } - - return nil -} - -func writeCacheFile(filename string, fileMode os.FileMode, t token) (err error) { - var f *os.File - f, err = os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_RDWR, fileMode) - if err != nil { - return fmt.Errorf("failed to create cached SSO token file %w", err) - } - - defer func() { - closeErr := f.Close() - if err == nil && closeErr != nil { - err = fmt.Errorf("failed to close cached SSO token file, %w", closeErr) - } - }() - - encoder := json.NewEncoder(f) - - if err = encoder.Encode(t); err != nil { - return fmt.Errorf("failed to serialize cached SSO token, %w", err) - } - - return nil -} - -type rfc3339 time.Time - -func parseRFC3339(v string) (rfc3339, error) { - parsed, err := time.Parse(time.RFC3339, v) - if err != nil { - return rfc3339{}, fmt.Errorf("expected RFC3339 timestamp: %w", err) - } - - return rfc3339(parsed), nil -} - -func (r *rfc3339) UnmarshalJSON(bytes []byte) (err error) { - var value string - - // Use JSON unmarshal to unescape the quoted value making use of JSON's - // unquoting rules. - if err = json.Unmarshal(bytes, &value); err != nil { - return err - } - - *r, err = parseRFC3339(value) - - return nil -} - -func (r *rfc3339) MarshalJSON() ([]byte, error) { - value := time.Time(*r).UTC().Format(time.RFC3339) - - // Use JSON unmarshal to unescape the quoted value making use of JSON's - // quoting rules. - return json.Marshal(value) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_credentials_provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_credentials_provider.go deleted file mode 100644 index 8c230be..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_credentials_provider.go +++ /dev/null @@ -1,153 +0,0 @@ -package ssocreds - -import ( - "context" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/aws-sdk-go-v2/service/sso" -) - -// ProviderName is the name of the provider used to specify the source of -// credentials. -const ProviderName = "SSOProvider" - -// GetRoleCredentialsAPIClient is a API client that implements the -// GetRoleCredentials operation. -type GetRoleCredentialsAPIClient interface { - GetRoleCredentials(context.Context, *sso.GetRoleCredentialsInput, ...func(*sso.Options)) ( - *sso.GetRoleCredentialsOutput, error, - ) -} - -// Options is the Provider options structure. -type Options struct { - // The Client which is configured for the AWS Region where the AWS SSO user - // portal is located. - Client GetRoleCredentialsAPIClient - - // The AWS account that is assigned to the user. - AccountID string - - // The role name that is assigned to the user. - RoleName string - - // The URL that points to the organization's AWS Single Sign-On (AWS SSO) - // user portal. - StartURL string - - // The filepath the cached token will be retrieved from. If unset Provider will - // use the startURL to determine the filepath at. - // - // ~/.aws/sso/cache/.json - // - // If custom cached token filepath is used, the Provider's startUrl - // parameter will be ignored. - CachedTokenFilepath string - - // Used by the SSOCredentialProvider if a token configuration - // profile is used in the shared config - SSOTokenProvider *SSOTokenProvider -} - -// Provider is an AWS credential provider that retrieves temporary AWS -// credentials by exchanging an SSO login token. -type Provider struct { - options Options - - cachedTokenFilepath string -} - -// New returns a new AWS Single Sign-On (AWS SSO) credential provider. The -// provided client is expected to be configured for the AWS Region where the -// AWS SSO user portal is located. -func New(client GetRoleCredentialsAPIClient, accountID, roleName, startURL string, optFns ...func(options *Options)) *Provider { - options := Options{ - Client: client, - AccountID: accountID, - RoleName: roleName, - StartURL: startURL, - } - - for _, fn := range optFns { - fn(&options) - } - - return &Provider{ - options: options, - cachedTokenFilepath: options.CachedTokenFilepath, - } -} - -// Retrieve retrieves temporary AWS credentials from the configured Amazon -// Single Sign-On (AWS SSO) user portal by exchanging the accessToken present -// in ~/.aws/sso/cache. However, if a token provider configuration exists -// in the shared config, then we ought to use the token provider rather then -// direct access on the cached token. -func (p *Provider) Retrieve(ctx context.Context) (aws.Credentials, error) { - var accessToken *string - if p.options.SSOTokenProvider != nil { - token, err := p.options.SSOTokenProvider.RetrieveBearerToken(ctx) - if err != nil { - return aws.Credentials{}, err - } - accessToken = &token.Value - } else { - if p.cachedTokenFilepath == "" { - cachedTokenFilepath, err := StandardCachedTokenFilepath(p.options.StartURL) - if err != nil { - return aws.Credentials{}, &InvalidTokenError{Err: err} - } - p.cachedTokenFilepath = cachedTokenFilepath - } - - tokenFile, err := loadCachedToken(p.cachedTokenFilepath) - if err != nil { - return aws.Credentials{}, &InvalidTokenError{Err: err} - } - - if tokenFile.ExpiresAt == nil || sdk.NowTime().After(time.Time(*tokenFile.ExpiresAt)) { - return aws.Credentials{}, &InvalidTokenError{} - } - accessToken = &tokenFile.AccessToken - } - - output, err := p.options.Client.GetRoleCredentials(ctx, &sso.GetRoleCredentialsInput{ - AccessToken: accessToken, - AccountId: &p.options.AccountID, - RoleName: &p.options.RoleName, - }) - if err != nil { - return aws.Credentials{}, err - } - - return aws.Credentials{ - AccessKeyID: aws.ToString(output.RoleCredentials.AccessKeyId), - SecretAccessKey: aws.ToString(output.RoleCredentials.SecretAccessKey), - SessionToken: aws.ToString(output.RoleCredentials.SessionToken), - CanExpire: true, - Expires: time.Unix(0, output.RoleCredentials.Expiration*int64(time.Millisecond)).UTC(), - Source: ProviderName, - AccountID: p.options.AccountID, - }, nil -} - -// InvalidTokenError is the error type that is returned if loaded token has -// expired or is otherwise invalid. To refresh the SSO session run AWS SSO -// login with the corresponding profile. -type InvalidTokenError struct { - Err error -} - -func (i *InvalidTokenError) Unwrap() error { - return i.Err -} - -func (i *InvalidTokenError) Error() string { - const msg = "the SSO session has expired or is invalid" - if i.Err == nil { - return msg - } - return msg + ": " + i.Err.Error() -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_token_provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_token_provider.go deleted file mode 100644 index 7f4fc54..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_token_provider.go +++ /dev/null @@ -1,147 +0,0 @@ -package ssocreds - -import ( - "context" - "fmt" - "os" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/aws-sdk-go-v2/service/ssooidc" - "github.com/aws/smithy-go/auth/bearer" -) - -// CreateTokenAPIClient provides the interface for the SSOTokenProvider's API -// client for calling CreateToken operation to refresh the SSO token. -type CreateTokenAPIClient interface { - CreateToken(context.Context, *ssooidc.CreateTokenInput, ...func(*ssooidc.Options)) ( - *ssooidc.CreateTokenOutput, error, - ) -} - -// SSOTokenProviderOptions provides the options for configuring the -// SSOTokenProvider. -type SSOTokenProviderOptions struct { - // Client that can be overridden - Client CreateTokenAPIClient - - // The set of API Client options to be applied when invoking the - // CreateToken operation. - ClientOptions []func(*ssooidc.Options) - - // The path the file containing the cached SSO token will be read from. - // Initialized the NewSSOTokenProvider's cachedTokenFilepath parameter. - CachedTokenFilepath string -} - -// SSOTokenProvider provides an utility for refreshing SSO AccessTokens for -// Bearer Authentication. The SSOTokenProvider can only be used to refresh -// already cached SSO Tokens. This utility cannot perform the initial SSO -// create token. -// -// The SSOTokenProvider is not safe to use concurrently. It must be wrapped in -// a utility such as smithy-go's auth/bearer#TokenCache. The SDK's -// config.LoadDefaultConfig will automatically wrap the SSOTokenProvider with -// the smithy-go TokenCache, if the external configuration loaded configured -// for an SSO session. -// -// The initial SSO create token should be preformed with the AWS CLI before the -// Go application using the SSOTokenProvider will need to retrieve the SSO -// token. If the AWS CLI has not created the token cache file, this provider -// will return an error when attempting to retrieve the cached token. -// -// This provider will attempt to refresh the cached SSO token periodically if -// needed when RetrieveBearerToken is called. -// -// A utility such as the AWS CLI must be used to initially create the SSO -// session and cached token file. -// https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html -type SSOTokenProvider struct { - options SSOTokenProviderOptions -} - -var _ bearer.TokenProvider = (*SSOTokenProvider)(nil) - -// NewSSOTokenProvider returns an initialized SSOTokenProvider that will -// periodically refresh the SSO token cached stored in the cachedTokenFilepath. -// The cachedTokenFilepath file's content will be rewritten by the token -// provider when the token is refreshed. -// -// The client must be configured for the AWS region the SSO token was created for. -func NewSSOTokenProvider(client CreateTokenAPIClient, cachedTokenFilepath string, optFns ...func(o *SSOTokenProviderOptions)) *SSOTokenProvider { - options := SSOTokenProviderOptions{ - Client: client, - CachedTokenFilepath: cachedTokenFilepath, - } - for _, fn := range optFns { - fn(&options) - } - - provider := &SSOTokenProvider{ - options: options, - } - - return provider -} - -// RetrieveBearerToken returns the SSO token stored in the cachedTokenFilepath -// the SSOTokenProvider was created with. If the token has expired -// RetrieveBearerToken will attempt to refresh it. If the token cannot be -// refreshed or is not present an error will be returned. -// -// A utility such as the AWS CLI must be used to initially create the SSO -// session and cached token file. https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html -func (p SSOTokenProvider) RetrieveBearerToken(ctx context.Context) (bearer.Token, error) { - cachedToken, err := loadCachedToken(p.options.CachedTokenFilepath) - if err != nil { - return bearer.Token{}, err - } - - if cachedToken.ExpiresAt != nil && sdk.NowTime().After(time.Time(*cachedToken.ExpiresAt)) { - cachedToken, err = p.refreshToken(ctx, cachedToken) - if err != nil { - return bearer.Token{}, fmt.Errorf("refresh cached SSO token failed, %w", err) - } - } - - expiresAt := aws.ToTime((*time.Time)(cachedToken.ExpiresAt)) - return bearer.Token{ - Value: cachedToken.AccessToken, - CanExpire: !expiresAt.IsZero(), - Expires: expiresAt, - }, nil -} - -func (p SSOTokenProvider) refreshToken(ctx context.Context, cachedToken token) (token, error) { - if cachedToken.ClientSecret == "" || cachedToken.ClientID == "" || cachedToken.RefreshToken == "" { - return token{}, fmt.Errorf("cached SSO token is expired, or not present, and cannot be refreshed") - } - - createResult, err := p.options.Client.CreateToken(ctx, &ssooidc.CreateTokenInput{ - ClientId: &cachedToken.ClientID, - ClientSecret: &cachedToken.ClientSecret, - RefreshToken: &cachedToken.RefreshToken, - GrantType: aws.String("refresh_token"), - }, p.options.ClientOptions...) - if err != nil { - return token{}, fmt.Errorf("unable to refresh SSO token, %w", err) - } - - expiresAt := sdk.NowTime().Add(time.Duration(createResult.ExpiresIn) * time.Second) - - cachedToken.AccessToken = aws.ToString(createResult.AccessToken) - cachedToken.ExpiresAt = (*rfc3339)(&expiresAt) - cachedToken.RefreshToken = aws.ToString(createResult.RefreshToken) - - fileInfo, err := os.Stat(p.options.CachedTokenFilepath) - if err != nil { - return token{}, fmt.Errorf("failed to stat cached SSO token file %w", err) - } - - if err = storeCachedToken(p.options.CachedTokenFilepath, cachedToken, fileInfo.Mode()); err != nil { - return token{}, fmt.Errorf("unable to cache refreshed SSO token, %w", err) - } - - return cachedToken, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/static_provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/static_provider.go deleted file mode 100644 index d525cac..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/static_provider.go +++ /dev/null @@ -1,53 +0,0 @@ -package credentials - -import ( - "context" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -const ( - // StaticCredentialsName provides a name of Static provider - StaticCredentialsName = "StaticCredentials" -) - -// StaticCredentialsEmptyError is emitted when static credentials are empty. -type StaticCredentialsEmptyError struct{} - -func (*StaticCredentialsEmptyError) Error() string { - return "static credentials are empty" -} - -// A StaticCredentialsProvider is a set of credentials which are set, and will -// never expire. -type StaticCredentialsProvider struct { - Value aws.Credentials -} - -// NewStaticCredentialsProvider return a StaticCredentialsProvider initialized with the AWS -// credentials passed in. -func NewStaticCredentialsProvider(key, secret, session string) StaticCredentialsProvider { - return StaticCredentialsProvider{ - Value: aws.Credentials{ - AccessKeyID: key, - SecretAccessKey: secret, - SessionToken: session, - }, - } -} - -// Retrieve returns the credentials or error if the credentials are invalid. -func (s StaticCredentialsProvider) Retrieve(_ context.Context) (aws.Credentials, error) { - v := s.Value - if v.AccessKeyID == "" || v.SecretAccessKey == "" { - return aws.Credentials{ - Source: StaticCredentialsName, - }, &StaticCredentialsEmptyError{} - } - - if len(v.Source) == 0 { - v.Source = StaticCredentialsName - } - - return v, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/assume_role_provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/assume_role_provider.go deleted file mode 100644 index 4c7f799..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/assume_role_provider.go +++ /dev/null @@ -1,326 +0,0 @@ -// Package stscreds are credential Providers to retrieve STS AWS credentials. -// -// STS provides multiple ways to retrieve credentials which can be used when making -// future AWS service API operation calls. -// -// The SDK will ensure that per instance of credentials.Credentials all requests -// to refresh the credentials will be synchronized. But, the SDK is unable to -// ensure synchronous usage of the AssumeRoleProvider if the value is shared -// between multiple Credentials or service clients. -// -// # Assume Role -// -// To assume an IAM role using STS with the SDK you can create a new Credentials -// with the SDKs's stscreds package. -// -// // Initial credentials loaded from SDK's default credential chain. Such as -// // the environment, shared credentials (~/.aws/credentials), or EC2 Instance -// // Role. These credentials will be used to to make the STS Assume Role API. -// cfg, err := config.LoadDefaultConfig(context.TODO()) -// if err != nil { -// panic(err) -// } -// -// // Create the credentials from AssumeRoleProvider to assume the role -// // referenced by the "myRoleARN" ARN. -// stsSvc := sts.NewFromConfig(cfg) -// creds := stscreds.NewAssumeRoleProvider(stsSvc, "myRoleArn") -// -// cfg.Credentials = aws.NewCredentialsCache(creds) -// -// // Create service client value configured for credentials -// // from assumed role. -// svc := s3.NewFromConfig(cfg) -// -// # Assume Role with custom MFA Token provider -// -// To assume an IAM role with a MFA token you can either specify a custom MFA -// token provider or use the SDK's built in StdinTokenProvider that will prompt -// the user for a token code each time the credentials need to to be refreshed. -// Specifying a custom token provider allows you to control where the token -// code is retrieved from, and how it is refreshed. -// -// With a custom token provider, the provider is responsible for refreshing the -// token code when called. -// -// cfg, err := config.LoadDefaultConfig(context.TODO()) -// if err != nil { -// panic(err) -// } -// -// staticTokenProvider := func() (string, error) { -// return someTokenCode, nil -// } -// -// // Create the credentials from AssumeRoleProvider to assume the role -// // referenced by the "myRoleARN" ARN using the MFA token code provided. -// creds := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), "myRoleArn", func(o *stscreds.AssumeRoleOptions) { -// o.SerialNumber = aws.String("myTokenSerialNumber") -// o.TokenProvider = staticTokenProvider -// }) -// -// cfg.Credentials = aws.NewCredentialsCache(creds) -// -// // Create service client value configured for credentials -// // from assumed role. -// svc := s3.NewFromConfig(cfg) -// -// # Assume Role with MFA Token Provider -// -// To assume an IAM role with MFA for longer running tasks where the credentials -// may need to be refreshed setting the TokenProvider field of AssumeRoleProvider -// will allow the credential provider to prompt for new MFA token code when the -// role's credentials need to be refreshed. -// -// The StdinTokenProvider function is available to prompt on stdin to retrieve -// the MFA token code from the user. You can also implement custom prompts by -// satisfying the TokenProvider function signature. -// -// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will -// have undesirable results as the StdinTokenProvider will not be synchronized. A -// single Credentials with an AssumeRoleProvider can be shared safely. -// -// cfg, err := config.LoadDefaultConfig(context.TODO()) -// if err != nil { -// panic(err) -// } -// -// // Create the credentials from AssumeRoleProvider to assume the role -// // referenced by the "myRoleARN" ARN using the MFA token code provided. -// creds := stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg), "myRoleArn", func(o *stscreds.AssumeRoleOptions) { -// o.SerialNumber = aws.String("myTokenSerialNumber") -// o.TokenProvider = stscreds.StdinTokenProvider -// }) -// -// cfg.Credentials = aws.NewCredentialsCache(creds) -// -// // Create service client value configured for credentials -// // from assumed role. -// svc := s3.NewFromConfig(cfg) -package stscreds - -import ( - "context" - "fmt" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/service/sts" - "github.com/aws/aws-sdk-go-v2/service/sts/types" -) - -// StdinTokenProvider will prompt on stdout and read from stdin for a string value. -// An error is returned if reading from stdin fails. -// -// Use this function go read MFA tokens from stdin. The function makes no attempt -// to make atomic prompts from stdin across multiple gorouties. -// -// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will -// have undesirable results as the StdinTokenProvider will not be synchronized. A -// single Credentials with an AssumeRoleProvider can be shared safely -// -// Will wait forever until something is provided on the stdin. -func StdinTokenProvider() (string, error) { - var v string - fmt.Printf("Assume Role MFA token code: ") - _, err := fmt.Scanln(&v) - - return v, err -} - -// ProviderName provides a name of AssumeRole provider -const ProviderName = "AssumeRoleProvider" - -// AssumeRoleAPIClient is a client capable of the STS AssumeRole operation. -type AssumeRoleAPIClient interface { - AssumeRole(ctx context.Context, params *sts.AssumeRoleInput, optFns ...func(*sts.Options)) (*sts.AssumeRoleOutput, error) -} - -// DefaultDuration is the default amount of time in minutes that the -// credentials will be valid for. This value is only used by AssumeRoleProvider -// for specifying the default expiry duration of an assume role. -// -// Other providers such as WebIdentityRoleProvider do not use this value, and -// instead rely on STS API's default parameter handing to assign a default -// value. -var DefaultDuration = time.Duration(15) * time.Minute - -// AssumeRoleProvider retrieves temporary credentials from the STS service, and -// keeps track of their expiration time. -// -// This credential provider will be used by the SDKs default credential change -// when shared configuration is enabled, and the shared config or shared credentials -// file configure assume role. See Session docs for how to do this. -// -// AssumeRoleProvider does not provide any synchronization and it is not safe -// to share this value across multiple Credentials, Sessions, or service clients -// without also sharing the same Credentials instance. -type AssumeRoleProvider struct { - options AssumeRoleOptions -} - -// AssumeRoleOptions is the configurable options for AssumeRoleProvider -type AssumeRoleOptions struct { - // Client implementation of the AssumeRole operation. Required - Client AssumeRoleAPIClient - - // IAM Role ARN to be assumed. Required - RoleARN string - - // Session name, if you wish to uniquely identify this session. - RoleSessionName string - - // Expiry duration of the STS credentials. Defaults to 15 minutes if not set. - Duration time.Duration - - // Optional ExternalID to pass along, defaults to nil if not set. - ExternalID *string - - // The policy plain text must be 2048 bytes or shorter. However, an internal - // conversion compresses it into a packed binary format with a separate limit. - // The PackedPolicySize response element indicates by percentage how close to - // the upper size limit the policy is, with 100% equaling the maximum allowed - // size. - Policy *string - - // The ARNs of IAM managed policies you want to use as managed session policies. - // The policies must exist in the same account as the role. - // - // This parameter is optional. You can provide up to 10 managed policy ARNs. - // However, the plain text that you use for both inline and managed session - // policies can't exceed 2,048 characters. - // - // An AWS conversion compresses the passed session policies and session tags - // into a packed binary format that has a separate limit. Your request can fail - // for this limit even if your plain text meets the other requirements. The - // PackedPolicySize response element indicates by percentage how close the policies - // and tags for your request are to the upper size limit. - // - // Passing policies to this operation returns new temporary credentials. The - // resulting session's permissions are the intersection of the role's identity-based - // policy and the session policies. You can use the role's temporary credentials - // in subsequent AWS API calls to access resources in the account that owns - // the role. You cannot use session policies to grant more permissions than - // those allowed by the identity-based policy of the role that is being assumed. - // For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) - // in the IAM User Guide. - PolicyARNs []types.PolicyDescriptorType - - // The identification number of the MFA device that is associated with the user - // who is making the AssumeRole call. Specify this value if the trust policy - // of the role being assumed includes a condition that requires MFA authentication. - // The value is either the serial number for a hardware device (such as GAHT12345678) - // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). - SerialNumber *string - - // The source identity specified by the principal that is calling the AssumeRole - // operation. You can require users to specify a source identity when they assume a - // role. You do this by using the sts:SourceIdentity condition key in a role trust - // policy. You can use source identity information in CloudTrail logs to determine - // who took actions with a role. You can use the aws:SourceIdentity condition key - // to further control access to Amazon Web Services resources based on the value of - // source identity. For more information about using source identity, see Monitor - // and control actions taken with assumed roles - // (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html) - // in the IAM User Guide. - SourceIdentity *string - - // Async method of providing MFA token code for assuming an IAM role with MFA. - // The value returned by the function will be used as the TokenCode in the Retrieve - // call. See StdinTokenProvider for a provider that prompts and reads from stdin. - // - // This token provider will be called when ever the assumed role's - // credentials need to be refreshed when SerialNumber is set. - TokenProvider func() (string, error) - - // A list of session tags that you want to pass. Each session tag consists of a key - // name and an associated value. For more information about session tags, see - // Tagging STS Sessions - // (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html) in the - // IAM User Guide. This parameter is optional. You can pass up to 50 session tags. - Tags []types.Tag - - // A list of keys for session tags that you want to set as transitive. If you set a - // tag key as transitive, the corresponding key and value passes to subsequent - // sessions in a role chain. For more information, see Chaining Roles with Session - // Tags - // (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining) - // in the IAM User Guide. This parameter is optional. - TransitiveTagKeys []string -} - -// NewAssumeRoleProvider constructs and returns a credentials provider that -// will retrieve credentials by assuming a IAM role using STS. -func NewAssumeRoleProvider(client AssumeRoleAPIClient, roleARN string, optFns ...func(*AssumeRoleOptions)) *AssumeRoleProvider { - o := AssumeRoleOptions{ - Client: client, - RoleARN: roleARN, - } - - for _, fn := range optFns { - fn(&o) - } - - return &AssumeRoleProvider{ - options: o, - } -} - -// Retrieve generates a new set of temporary credentials using STS. -func (p *AssumeRoleProvider) Retrieve(ctx context.Context) (aws.Credentials, error) { - // Apply defaults where parameters are not set. - if len(p.options.RoleSessionName) == 0 { - // Try to work out a role name that will hopefully end up unique. - p.options.RoleSessionName = fmt.Sprintf("aws-go-sdk-%d", time.Now().UTC().UnixNano()) - } - if p.options.Duration == 0 { - // Expire as often as AWS permits. - p.options.Duration = DefaultDuration - } - input := &sts.AssumeRoleInput{ - DurationSeconds: aws.Int32(int32(p.options.Duration / time.Second)), - PolicyArns: p.options.PolicyARNs, - RoleArn: aws.String(p.options.RoleARN), - RoleSessionName: aws.String(p.options.RoleSessionName), - ExternalId: p.options.ExternalID, - SourceIdentity: p.options.SourceIdentity, - Tags: p.options.Tags, - TransitiveTagKeys: p.options.TransitiveTagKeys, - } - if p.options.Policy != nil { - input.Policy = p.options.Policy - } - if p.options.SerialNumber != nil { - if p.options.TokenProvider != nil { - input.SerialNumber = p.options.SerialNumber - code, err := p.options.TokenProvider() - if err != nil { - return aws.Credentials{}, err - } - input.TokenCode = aws.String(code) - } else { - return aws.Credentials{}, fmt.Errorf("assume role with MFA enabled, but TokenProvider is not set") - } - } - - resp, err := p.options.Client.AssumeRole(ctx, input) - if err != nil { - return aws.Credentials{Source: ProviderName}, err - } - - var accountID string - if resp.AssumedRoleUser != nil { - accountID = getAccountID(resp.AssumedRoleUser) - } - - return aws.Credentials{ - AccessKeyID: *resp.Credentials.AccessKeyId, - SecretAccessKey: *resp.Credentials.SecretAccessKey, - SessionToken: *resp.Credentials.SessionToken, - Source: ProviderName, - - CanExpire: true, - Expires: *resp.Credentials.Expiration, - AccountID: accountID, - }, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/web_identity_provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/web_identity_provider.go deleted file mode 100644 index b4b7197..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/web_identity_provider.go +++ /dev/null @@ -1,169 +0,0 @@ -package stscreds - -import ( - "context" - "fmt" - "io/ioutil" - "strconv" - "strings" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/aws/retry" - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/aws-sdk-go-v2/service/sts" - "github.com/aws/aws-sdk-go-v2/service/sts/types" -) - -var invalidIdentityTokenExceptionCode = (&types.InvalidIdentityTokenException{}).ErrorCode() - -const ( - // WebIdentityProviderName is the web identity provider name - WebIdentityProviderName = "WebIdentityCredentials" -) - -// AssumeRoleWithWebIdentityAPIClient is a client capable of the STS AssumeRoleWithWebIdentity operation. -type AssumeRoleWithWebIdentityAPIClient interface { - AssumeRoleWithWebIdentity(ctx context.Context, params *sts.AssumeRoleWithWebIdentityInput, optFns ...func(*sts.Options)) (*sts.AssumeRoleWithWebIdentityOutput, error) -} - -// WebIdentityRoleProvider is used to retrieve credentials using -// an OIDC token. -type WebIdentityRoleProvider struct { - options WebIdentityRoleOptions -} - -// WebIdentityRoleOptions is a structure of configurable options for WebIdentityRoleProvider -type WebIdentityRoleOptions struct { - // Client implementation of the AssumeRoleWithWebIdentity operation. Required - Client AssumeRoleWithWebIdentityAPIClient - - // JWT Token Provider. Required - TokenRetriever IdentityTokenRetriever - - // IAM Role ARN to assume. Required - RoleARN string - - // Session name, if you wish to uniquely identify this session. - RoleSessionName string - - // Expiry duration of the STS credentials. STS will assign a default expiry - // duration if this value is unset. This is different from the Duration - // option of AssumeRoleProvider, which automatically assigns 15 minutes if - // Duration is unset. - // - // See the STS AssumeRoleWithWebIdentity API reference guide for more - // information on defaults. - // https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html - Duration time.Duration - - // An IAM policy in JSON format that you want to use as an inline session policy. - Policy *string - - // The Amazon Resource Names (ARNs) of the IAM managed policies that you - // want to use as managed session policies. The policies must exist in the - // same account as the role. - PolicyARNs []types.PolicyDescriptorType -} - -// IdentityTokenRetriever is an interface for retrieving a JWT -type IdentityTokenRetriever interface { - GetIdentityToken() ([]byte, error) -} - -// IdentityTokenFile is for retrieving an identity token from the given file name -type IdentityTokenFile string - -// GetIdentityToken retrieves the JWT token from the file and returns the contents as a []byte -func (j IdentityTokenFile) GetIdentityToken() ([]byte, error) { - b, err := ioutil.ReadFile(string(j)) - if err != nil { - return nil, fmt.Errorf("unable to read file at %s: %v", string(j), err) - } - - return b, nil -} - -// NewWebIdentityRoleProvider will return a new WebIdentityRoleProvider with the -// provided stsiface.ClientAPI -func NewWebIdentityRoleProvider(client AssumeRoleWithWebIdentityAPIClient, roleARN string, tokenRetriever IdentityTokenRetriever, optFns ...func(*WebIdentityRoleOptions)) *WebIdentityRoleProvider { - o := WebIdentityRoleOptions{ - Client: client, - RoleARN: roleARN, - TokenRetriever: tokenRetriever, - } - - for _, fn := range optFns { - fn(&o) - } - - return &WebIdentityRoleProvider{options: o} -} - -// Retrieve will attempt to assume a role from a token which is located at -// 'WebIdentityTokenFilePath' specified destination and if that is empty an -// error will be returned. -func (p *WebIdentityRoleProvider) Retrieve(ctx context.Context) (aws.Credentials, error) { - b, err := p.options.TokenRetriever.GetIdentityToken() - if err != nil { - return aws.Credentials{}, fmt.Errorf("failed to retrieve jwt from provide source, %w", err) - } - - sessionName := p.options.RoleSessionName - if len(sessionName) == 0 { - // session name is used to uniquely identify a session. This simply - // uses unix time in nanoseconds to uniquely identify sessions. - sessionName = strconv.FormatInt(sdk.NowTime().UnixNano(), 10) - } - input := &sts.AssumeRoleWithWebIdentityInput{ - PolicyArns: p.options.PolicyARNs, - RoleArn: &p.options.RoleARN, - RoleSessionName: &sessionName, - WebIdentityToken: aws.String(string(b)), - } - if p.options.Duration != 0 { - // If set use the value, otherwise STS will assign a default expiration duration. - input.DurationSeconds = aws.Int32(int32(p.options.Duration / time.Second)) - } - if p.options.Policy != nil { - input.Policy = p.options.Policy - } - - resp, err := p.options.Client.AssumeRoleWithWebIdentity(ctx, input, func(options *sts.Options) { - options.Retryer = retry.AddWithErrorCodes(options.Retryer, invalidIdentityTokenExceptionCode) - }) - if err != nil { - return aws.Credentials{}, fmt.Errorf("failed to retrieve credentials, %w", err) - } - - var accountID string - if resp.AssumedRoleUser != nil { - accountID = getAccountID(resp.AssumedRoleUser) - } - - // InvalidIdentityToken error is a temporary error that can occur - // when assuming an Role with a JWT web identity token. - - value := aws.Credentials{ - AccessKeyID: aws.ToString(resp.Credentials.AccessKeyId), - SecretAccessKey: aws.ToString(resp.Credentials.SecretAccessKey), - SessionToken: aws.ToString(resp.Credentials.SessionToken), - Source: WebIdentityProviderName, - CanExpire: true, - Expires: *resp.Credentials.Expiration, - AccountID: accountID, - } - return value, nil -} - -// extract accountID from arn with format "arn:partition:service:region:account-id:[resource-section]" -func getAccountID(u *types.AssumedRoleUser) string { - if u.Arn == nil { - return "" - } - parts := strings.Split(*u.Arn, ":") - if len(parts) < 5 { - return "" - } - return parts[4] -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md deleted file mode 100644 index d90cc27..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md +++ /dev/null @@ -1,422 +0,0 @@ -# v1.16.27 (2025-01-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.26 (2025-01-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.25 (2025-01-24) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v1.16.24 (2025-01-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.23 (2025-01-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.22 (2024-12-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.21 (2024-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.20 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.19 (2024-11-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.18 (2024-10-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.17 (2024-10-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.16 (2024-10-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.15 (2024-10-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.14 (2024-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.13 (2024-09-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.12 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.11 (2024-07-10.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.10 (2024-07-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.9 (2024-06-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.8 (2024-06-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.7 (2024-06-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.6 (2024-06-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.5 (2024-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.4 (2024-06-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.3 (2024-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.2 (2024-05-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.1 (2024-03-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.0 (2024-03-21) - -* **Feature**: Add config switch `DisableDefaultTimeout` that allows you to disable the default operation timeout (5 seconds) for IMDS calls. - -# v1.15.4 (2024-03-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.3 (2024-03-07) - -* **Bug Fix**: Remove dependency on go-cmp. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.2 (2024-02-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.1 (2024-02-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.11 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.10 (2023-12-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.9 (2023-12-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.8 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.7 (2023-11-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.6 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.5 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.4 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.3 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.2 (2023-11-02) - -* No change notes available for this release. - -# v1.14.1 (2023-11-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.13 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.12 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.11 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.10 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.9 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.8 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.7 (2023-07-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.6 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.5 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.4 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.3 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.2 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.1 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.0 (2023-03-14) - -* **Feature**: Add flag to disable IMDSv1 fallback - -# v1.12.24 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.23 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.22 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.21 (2022-12-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.20 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.19 (2022-10-24) - -* **Bug Fix**: Fixes an issue that prevented logging of the API request or responses when the respective log modes were enabled. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.18 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.17 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.16 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.15 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.14 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.13 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.12 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.11 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.10 (2022-08-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.9 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.8 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.7 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.6 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.5 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.4 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.3 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.2 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.1 (2022-03-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.0 (2022-02-24) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.0 (2022-01-14) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.0 (2022-01-07) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.2 (2021-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.1 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.0 (2021-11-06) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.7.0 (2021-10-21) - -* **Feature**: Updated to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.0 (2021-10-11) - -* **Feature**: Respect passed in Context Deadline/Timeout. Updates the IMDS Client operations to not override the passed in Context's Deadline or Timeout options. If an Client operation is called with a Context with a Deadline or Timeout, the client will no longer override it with the client's default timeout. -* **Bug Fix**: Fix IMDS client's response handling and operation timeout race. Fixes #1253 -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.1 (2021-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.0 (2021-08-27) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.1 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.0 (2021-08-04) - -* **Feature**: adds error handling for defered close calls -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.0 (2021-07-15) - -* **Feature**: Support has been added for EC2 IPv6-enabled Instance Metadata Service Endpoints. -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.0 (2021-06-25) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.1 (2021-05-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.0 (2021-05-14) - -* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting. -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_client.go deleted file mode 100644 index 3f4a10e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_client.go +++ /dev/null @@ -1,352 +0,0 @@ -package imds - -import ( - "context" - "fmt" - "net" - "net/http" - "os" - "strings" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/aws/retry" - awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" - internalconfig "github.com/aws/aws-sdk-go-v2/feature/ec2/imds/internal/config" - "github.com/aws/smithy-go" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// ServiceID provides the unique name of this API client -const ServiceID = "ec2imds" - -// Client provides the API client for interacting with the Amazon EC2 Instance -// Metadata Service API. -type Client struct { - options Options -} - -// ClientEnableState provides an enumeration if the client is enabled, -// disabled, or default behavior. -type ClientEnableState = internalconfig.ClientEnableState - -// Enumeration values for ClientEnableState -const ( - ClientDefaultEnableState ClientEnableState = internalconfig.ClientDefaultEnableState // default behavior - ClientDisabled ClientEnableState = internalconfig.ClientDisabled // client disabled - ClientEnabled ClientEnableState = internalconfig.ClientEnabled // client enabled -) - -// EndpointModeState is an enum configuration variable describing the client endpoint mode. -// Not configurable directly, but used when using the NewFromConfig. -type EndpointModeState = internalconfig.EndpointModeState - -// Enumeration values for EndpointModeState -const ( - EndpointModeStateUnset EndpointModeState = internalconfig.EndpointModeStateUnset - EndpointModeStateIPv4 EndpointModeState = internalconfig.EndpointModeStateIPv4 - EndpointModeStateIPv6 EndpointModeState = internalconfig.EndpointModeStateIPv6 -) - -const ( - disableClientEnvVar = "AWS_EC2_METADATA_DISABLED" - - // Client endpoint options - endpointEnvVar = "AWS_EC2_METADATA_SERVICE_ENDPOINT" - - defaultIPv4Endpoint = "http://169.254.169.254" - defaultIPv6Endpoint = "http://[fd00:ec2::254]" -) - -// New returns an initialized Client based on the functional options. Provide -// additional functional options to further configure the behavior of the client, -// such as changing the client's endpoint or adding custom middleware behavior. -func New(options Options, optFns ...func(*Options)) *Client { - options = options.Copy() - - for _, fn := range optFns { - fn(&options) - } - - options.HTTPClient = resolveHTTPClient(options.HTTPClient) - - if options.Retryer == nil { - options.Retryer = retry.NewStandard() - } - options.Retryer = retry.AddWithMaxBackoffDelay(options.Retryer, 1*time.Second) - - if options.ClientEnableState == ClientDefaultEnableState { - if v := os.Getenv(disableClientEnvVar); strings.EqualFold(v, "true") { - options.ClientEnableState = ClientDisabled - } - } - - if len(options.Endpoint) == 0 { - if v := os.Getenv(endpointEnvVar); len(v) != 0 { - options.Endpoint = v - } - } - - client := &Client{ - options: options, - } - - if client.options.tokenProvider == nil && !client.options.disableAPIToken { - client.options.tokenProvider = newTokenProvider(client, defaultTokenTTL) - } - - return client -} - -// NewFromConfig returns an initialized Client based the AWS SDK config, and -// functional options. Provide additional functional options to further -// configure the behavior of the client, such as changing the client's endpoint -// or adding custom middleware behavior. -func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { - opts := Options{ - APIOptions: append([]func(*middleware.Stack) error{}, cfg.APIOptions...), - HTTPClient: cfg.HTTPClient, - ClientLogMode: cfg.ClientLogMode, - Logger: cfg.Logger, - } - - if cfg.Retryer != nil { - opts.Retryer = cfg.Retryer() - } - - resolveClientEnableState(cfg, &opts) - resolveEndpointConfig(cfg, &opts) - resolveEndpointModeConfig(cfg, &opts) - resolveEnableFallback(cfg, &opts) - - return New(opts, optFns...) -} - -// Options provides the fields for configuring the API client's behavior. -type Options struct { - // Set of options to modify how an operation is invoked. These apply to all - // operations invoked for this client. Use functional options on operation - // call to modify this list for per operation behavior. - APIOptions []func(*middleware.Stack) error - - // The endpoint the client will use to retrieve EC2 instance metadata. - // - // Specifies the EC2 Instance Metadata Service endpoint to use. If specified it overrides EndpointMode. - // - // If unset, and the environment variable AWS_EC2_METADATA_SERVICE_ENDPOINT - // has a value the client will use the value of the environment variable as - // the endpoint for operation calls. - // - // AWS_EC2_METADATA_SERVICE_ENDPOINT=http://[::1] - Endpoint string - - // The endpoint selection mode the client will use if no explicit endpoint is provided using the Endpoint field. - // - // Setting EndpointMode to EndpointModeStateIPv4 will configure the client to use the default EC2 IPv4 endpoint. - // Setting EndpointMode to EndpointModeStateIPv6 will configure the client to use the default EC2 IPv6 endpoint. - // - // By default if EndpointMode is not set (EndpointModeStateUnset) than the default endpoint selection mode EndpointModeStateIPv4. - EndpointMode EndpointModeState - - // The HTTP client to invoke API calls with. Defaults to client's default - // HTTP implementation if nil. - HTTPClient HTTPClient - - // Retryer guides how HTTP requests should be retried in case of recoverable - // failures. When nil the API client will use a default retryer. - Retryer aws.Retryer - - // Changes if the EC2 Instance Metadata client is enabled or not. Client - // will default to enabled if not set to ClientDisabled. When the client is - // disabled it will return an error for all operation calls. - // - // If ClientEnableState value is ClientDefaultEnableState (default value), - // and the environment variable "AWS_EC2_METADATA_DISABLED" is set to - // "true", the client will be disabled. - // - // AWS_EC2_METADATA_DISABLED=true - ClientEnableState ClientEnableState - - // Configures the events that will be sent to the configured logger. - ClientLogMode aws.ClientLogMode - - // The logger writer interface to write logging messages to. - Logger logging.Logger - - // Configure IMDSv1 fallback behavior. By default, the client will attempt - // to fall back to IMDSv1 as needed for backwards compatibility. When set to [aws.FalseTernary] - // the client will return any errors encountered from attempting to fetch a token - // instead of silently using the insecure data flow of IMDSv1. - // - // See [configuring IMDS] for more information. - // - // [configuring IMDS]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html - EnableFallback aws.Ternary - - // By default, all IMDS client operations enforce a 5-second timeout. You - // can disable that behavior with this setting. - DisableDefaultTimeout bool - - // provides the caching of API tokens used for operation calls. If unset, - // the API token will not be retrieved for the operation. - tokenProvider *tokenProvider - - // option to disable the API token provider for testing. - disableAPIToken bool -} - -// HTTPClient provides the interface for a client making HTTP requests with the -// API. -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) -} - -// Copy creates a copy of the API options. -func (o Options) Copy() Options { - to := o - to.APIOptions = append([]func(*middleware.Stack) error{}, o.APIOptions...) - return to -} - -// WithAPIOptions wraps the API middleware functions, as a functional option -// for the API Client Options. Use this helper to add additional functional -// options to the API client, or operation calls. -func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { - return func(o *Options) { - o.APIOptions = append(o.APIOptions, optFns...) - } -} - -func (c *Client) invokeOperation( - ctx context.Context, opID string, params interface{}, optFns []func(*Options), - stackFns ...func(*middleware.Stack, Options) error, -) ( - result interface{}, metadata middleware.Metadata, err error, -) { - stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) - options := c.options.Copy() - for _, fn := range optFns { - fn(&options) - } - - if options.ClientEnableState == ClientDisabled { - return nil, metadata, &smithy.OperationError{ - ServiceID: ServiceID, - OperationName: opID, - Err: fmt.Errorf( - "access disabled to EC2 IMDS via client option, or %q environment variable", - disableClientEnvVar), - } - } - - for _, fn := range stackFns { - if err := fn(stack, options); err != nil { - return nil, metadata, err - } - } - - for _, fn := range options.APIOptions { - if err := fn(stack); err != nil { - return nil, metadata, err - } - } - - handler := middleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack) - result, metadata, err = handler.Handle(ctx, params) - if err != nil { - return nil, metadata, &smithy.OperationError{ - ServiceID: ServiceID, - OperationName: opID, - Err: err, - } - } - - return result, metadata, err -} - -const ( - // HTTP client constants - defaultDialerTimeout = 250 * time.Millisecond - defaultResponseHeaderTimeout = 500 * time.Millisecond -) - -func resolveHTTPClient(client HTTPClient) HTTPClient { - if client == nil { - client = awshttp.NewBuildableClient() - } - - if c, ok := client.(*awshttp.BuildableClient); ok { - client = c. - WithDialerOptions(func(d *net.Dialer) { - // Use a custom Dial timeout for the EC2 Metadata service to account - // for the possibility the application might not be running in an - // environment with the service present. The client should fail fast in - // this case. - d.Timeout = defaultDialerTimeout - }). - WithTransportOptions(func(tr *http.Transport) { - // Use a custom Transport timeout for the EC2 Metadata service to - // account for the possibility that the application might be running in - // a container, and EC2Metadata service drops the connection after a - // single IP Hop. The client should fail fast in this case. - tr.ResponseHeaderTimeout = defaultResponseHeaderTimeout - }) - } - - return client -} - -func resolveClientEnableState(cfg aws.Config, options *Options) error { - if options.ClientEnableState != ClientDefaultEnableState { - return nil - } - value, found, err := internalconfig.ResolveClientEnableState(cfg.ConfigSources) - if err != nil || !found { - return err - } - options.ClientEnableState = value - return nil -} - -func resolveEndpointModeConfig(cfg aws.Config, options *Options) error { - if options.EndpointMode != EndpointModeStateUnset { - return nil - } - value, found, err := internalconfig.ResolveEndpointModeConfig(cfg.ConfigSources) - if err != nil || !found { - return err - } - options.EndpointMode = value - return nil -} - -func resolveEndpointConfig(cfg aws.Config, options *Options) error { - if len(options.Endpoint) != 0 { - return nil - } - value, found, err := internalconfig.ResolveEndpointConfig(cfg.ConfigSources) - if err != nil || !found { - return err - } - options.Endpoint = value - return nil -} - -func resolveEnableFallback(cfg aws.Config, options *Options) { - if options.EnableFallback != aws.UnknownTernary { - return - } - - disabled, ok := internalconfig.ResolveV1FallbackDisabled(cfg.ConfigSources) - if !ok { - return - } - - if disabled { - options.EnableFallback = aws.FalseTernary - } else { - options.EnableFallback = aws.TrueTernary - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetDynamicData.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetDynamicData.go deleted file mode 100644 index af58b6b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetDynamicData.go +++ /dev/null @@ -1,77 +0,0 @@ -package imds - -import ( - "context" - "fmt" - "io" - - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -const getDynamicDataPath = "/latest/dynamic" - -// GetDynamicData uses the path provided to request information from the EC2 -// instance metadata service for dynamic data. The content will be returned -// as a string, or error if the request failed. -func (c *Client) GetDynamicData(ctx context.Context, params *GetDynamicDataInput, optFns ...func(*Options)) (*GetDynamicDataOutput, error) { - if params == nil { - params = &GetDynamicDataInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetDynamicData", params, optFns, - addGetDynamicDataMiddleware, - ) - if err != nil { - return nil, err - } - - out := result.(*GetDynamicDataOutput) - out.ResultMetadata = metadata - return out, nil -} - -// GetDynamicDataInput provides the input parameters for the GetDynamicData -// operation. -type GetDynamicDataInput struct { - // The relative dynamic data path to retrieve. Can be empty string to - // retrieve a response containing a new line separated list of dynamic data - // resources available. - // - // Must not include the dynamic data base path. - // - // May include leading slash. If Path includes trailing slash the trailing - // slash will be included in the request for the resource. - Path string -} - -// GetDynamicDataOutput provides the output parameters for the GetDynamicData -// operation. -type GetDynamicDataOutput struct { - Content io.ReadCloser - - ResultMetadata middleware.Metadata -} - -func addGetDynamicDataMiddleware(stack *middleware.Stack, options Options) error { - return addAPIRequestMiddleware(stack, - options, - "GetDynamicData", - buildGetDynamicDataPath, - buildGetDynamicDataOutput) -} - -func buildGetDynamicDataPath(params interface{}) (string, error) { - p, ok := params.(*GetDynamicDataInput) - if !ok { - return "", fmt.Errorf("unknown parameter type %T", params) - } - - return appendURIPath(getDynamicDataPath, p.Path), nil -} - -func buildGetDynamicDataOutput(resp *smithyhttp.Response) (interface{}, error) { - return &GetDynamicDataOutput{ - Content: resp.Body, - }, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetIAMInfo.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetIAMInfo.go deleted file mode 100644 index 5111cc9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetIAMInfo.go +++ /dev/null @@ -1,103 +0,0 @@ -package imds - -import ( - "context" - "encoding/json" - "fmt" - "io" - "strings" - "time" - - "github.com/aws/smithy-go" - smithyio "github.com/aws/smithy-go/io" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -const getIAMInfoPath = getMetadataPath + "/iam/info" - -// GetIAMInfo retrieves an identity document describing an -// instance. Error is returned if the request fails or is unable to parse -// the response. -func (c *Client) GetIAMInfo( - ctx context.Context, params *GetIAMInfoInput, optFns ...func(*Options), -) ( - *GetIAMInfoOutput, error, -) { - if params == nil { - params = &GetIAMInfoInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetIAMInfo", params, optFns, - addGetIAMInfoMiddleware, - ) - if err != nil { - return nil, err - } - - out := result.(*GetIAMInfoOutput) - out.ResultMetadata = metadata - return out, nil -} - -// GetIAMInfoInput provides the input parameters for GetIAMInfo operation. -type GetIAMInfoInput struct{} - -// GetIAMInfoOutput provides the output parameters for GetIAMInfo operation. -type GetIAMInfoOutput struct { - IAMInfo - - ResultMetadata middleware.Metadata -} - -func addGetIAMInfoMiddleware(stack *middleware.Stack, options Options) error { - return addAPIRequestMiddleware(stack, - options, - "GetIAMInfo", - buildGetIAMInfoPath, - buildGetIAMInfoOutput, - ) -} - -func buildGetIAMInfoPath(params interface{}) (string, error) { - return getIAMInfoPath, nil -} - -func buildGetIAMInfoOutput(resp *smithyhttp.Response) (v interface{}, err error) { - defer func() { - closeErr := resp.Body.Close() - if err == nil { - err = closeErr - } else if closeErr != nil { - err = fmt.Errorf("response body close error: %v, original error: %w", closeErr, err) - } - }() - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(resp.Body, ringBuffer) - - imdsResult := &GetIAMInfoOutput{} - if err = json.NewDecoder(body).Decode(&imdsResult.IAMInfo); err != nil { - return nil, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode instance identity document, %w", err), - Snapshot: ringBuffer.Bytes(), - } - } - // Any code other success is an error - if !strings.EqualFold(imdsResult.Code, "success") { - return nil, fmt.Errorf("failed to get EC2 IMDS IAM info, %s", - imdsResult.Code) - } - - return imdsResult, nil -} - -// IAMInfo provides the shape for unmarshaling an IAM info from the metadata -// API. -type IAMInfo struct { - Code string - LastUpdated time.Time - InstanceProfileArn string - InstanceProfileID string -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetInstanceIdentityDocument.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetInstanceIdentityDocument.go deleted file mode 100644 index dc8c09e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetInstanceIdentityDocument.go +++ /dev/null @@ -1,110 +0,0 @@ -package imds - -import ( - "context" - "encoding/json" - "fmt" - "io" - "time" - - "github.com/aws/smithy-go" - smithyio "github.com/aws/smithy-go/io" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -const getInstanceIdentityDocumentPath = getDynamicDataPath + "/instance-identity/document" - -// GetInstanceIdentityDocument retrieves an identity document describing an -// instance. Error is returned if the request fails or is unable to parse -// the response. -func (c *Client) GetInstanceIdentityDocument( - ctx context.Context, params *GetInstanceIdentityDocumentInput, optFns ...func(*Options), -) ( - *GetInstanceIdentityDocumentOutput, error, -) { - if params == nil { - params = &GetInstanceIdentityDocumentInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetInstanceIdentityDocument", params, optFns, - addGetInstanceIdentityDocumentMiddleware, - ) - if err != nil { - return nil, err - } - - out := result.(*GetInstanceIdentityDocumentOutput) - out.ResultMetadata = metadata - return out, nil -} - -// GetInstanceIdentityDocumentInput provides the input parameters for -// GetInstanceIdentityDocument operation. -type GetInstanceIdentityDocumentInput struct{} - -// GetInstanceIdentityDocumentOutput provides the output parameters for -// GetInstanceIdentityDocument operation. -type GetInstanceIdentityDocumentOutput struct { - InstanceIdentityDocument - - ResultMetadata middleware.Metadata -} - -func addGetInstanceIdentityDocumentMiddleware(stack *middleware.Stack, options Options) error { - return addAPIRequestMiddleware(stack, - options, - "GetInstanceIdentityDocument", - buildGetInstanceIdentityDocumentPath, - buildGetInstanceIdentityDocumentOutput, - ) -} - -func buildGetInstanceIdentityDocumentPath(params interface{}) (string, error) { - return getInstanceIdentityDocumentPath, nil -} - -func buildGetInstanceIdentityDocumentOutput(resp *smithyhttp.Response) (v interface{}, err error) { - defer func() { - closeErr := resp.Body.Close() - if err == nil { - err = closeErr - } else if closeErr != nil { - err = fmt.Errorf("response body close error: %v, original error: %w", closeErr, err) - } - }() - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(resp.Body, ringBuffer) - - output := &GetInstanceIdentityDocumentOutput{} - if err = json.NewDecoder(body).Decode(&output.InstanceIdentityDocument); err != nil { - return nil, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode instance identity document, %w", err), - Snapshot: ringBuffer.Bytes(), - } - } - - return output, nil -} - -// InstanceIdentityDocument provides the shape for unmarshaling -// an instance identity document -type InstanceIdentityDocument struct { - DevpayProductCodes []string `json:"devpayProductCodes"` - MarketplaceProductCodes []string `json:"marketplaceProductCodes"` - AvailabilityZone string `json:"availabilityZone"` - PrivateIP string `json:"privateIp"` - Version string `json:"version"` - Region string `json:"region"` - InstanceID string `json:"instanceId"` - BillingProducts []string `json:"billingProducts"` - InstanceType string `json:"instanceType"` - AccountID string `json:"accountId"` - PendingTime time.Time `json:"pendingTime"` - ImageID string `json:"imageId"` - KernelID string `json:"kernelId"` - RamdiskID string `json:"ramdiskId"` - Architecture string `json:"architecture"` -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetMetadata.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetMetadata.go deleted file mode 100644 index 869bfc9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetMetadata.go +++ /dev/null @@ -1,77 +0,0 @@ -package imds - -import ( - "context" - "fmt" - "io" - - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -const getMetadataPath = "/latest/meta-data" - -// GetMetadata uses the path provided to request information from the Amazon -// EC2 Instance Metadata Service. The content will be returned as a string, or -// error if the request failed. -func (c *Client) GetMetadata(ctx context.Context, params *GetMetadataInput, optFns ...func(*Options)) (*GetMetadataOutput, error) { - if params == nil { - params = &GetMetadataInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetMetadata", params, optFns, - addGetMetadataMiddleware, - ) - if err != nil { - return nil, err - } - - out := result.(*GetMetadataOutput) - out.ResultMetadata = metadata - return out, nil -} - -// GetMetadataInput provides the input parameters for the GetMetadata -// operation. -type GetMetadataInput struct { - // The relative metadata path to retrieve. Can be empty string to retrieve - // a response containing a new line separated list of metadata resources - // available. - // - // Must not include the metadata base path. - // - // May include leading slash. If Path includes trailing slash the trailing slash - // will be included in the request for the resource. - Path string -} - -// GetMetadataOutput provides the output parameters for the GetMetadata -// operation. -type GetMetadataOutput struct { - Content io.ReadCloser - - ResultMetadata middleware.Metadata -} - -func addGetMetadataMiddleware(stack *middleware.Stack, options Options) error { - return addAPIRequestMiddleware(stack, - options, - "GetMetadata", - buildGetMetadataPath, - buildGetMetadataOutput) -} - -func buildGetMetadataPath(params interface{}) (string, error) { - p, ok := params.(*GetMetadataInput) - if !ok { - return "", fmt.Errorf("unknown parameter type %T", params) - } - - return appendURIPath(getMetadataPath, p.Path), nil -} - -func buildGetMetadataOutput(resp *smithyhttp.Response) (interface{}, error) { - return &GetMetadataOutput{ - Content: resp.Body, - }, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetRegion.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetRegion.go deleted file mode 100644 index 8c0572b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetRegion.go +++ /dev/null @@ -1,73 +0,0 @@ -package imds - -import ( - "context" - "fmt" - - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// GetRegion retrieves an identity document describing an -// instance. Error is returned if the request fails or is unable to parse -// the response. -func (c *Client) GetRegion( - ctx context.Context, params *GetRegionInput, optFns ...func(*Options), -) ( - *GetRegionOutput, error, -) { - if params == nil { - params = &GetRegionInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetRegion", params, optFns, - addGetRegionMiddleware, - ) - if err != nil { - return nil, err - } - - out := result.(*GetRegionOutput) - out.ResultMetadata = metadata - return out, nil -} - -// GetRegionInput provides the input parameters for GetRegion operation. -type GetRegionInput struct{} - -// GetRegionOutput provides the output parameters for GetRegion operation. -type GetRegionOutput struct { - Region string - - ResultMetadata middleware.Metadata -} - -func addGetRegionMiddleware(stack *middleware.Stack, options Options) error { - return addAPIRequestMiddleware(stack, - options, - "GetRegion", - buildGetInstanceIdentityDocumentPath, - buildGetRegionOutput, - ) -} - -func buildGetRegionOutput(resp *smithyhttp.Response) (interface{}, error) { - out, err := buildGetInstanceIdentityDocumentOutput(resp) - if err != nil { - return nil, err - } - - result, ok := out.(*GetInstanceIdentityDocumentOutput) - if !ok { - return nil, fmt.Errorf("unexpected instance identity document type, %T", out) - } - - region := result.Region - if len(region) == 0 { - return "", fmt.Errorf("instance metadata did not return a region value") - } - - return &GetRegionOutput{ - Region: region, - }, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetToken.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetToken.go deleted file mode 100644 index 1f9ee97..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetToken.go +++ /dev/null @@ -1,119 +0,0 @@ -package imds - -import ( - "context" - "fmt" - "io" - "strconv" - "strings" - "time" - - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -const getTokenPath = "/latest/api/token" -const tokenTTLHeader = "X-Aws-Ec2-Metadata-Token-Ttl-Seconds" - -// getToken uses the duration to return a token for EC2 IMDS, or an error if -// the request failed. -func (c *Client) getToken(ctx context.Context, params *getTokenInput, optFns ...func(*Options)) (*getTokenOutput, error) { - if params == nil { - params = &getTokenInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "getToken", params, optFns, - addGetTokenMiddleware, - ) - if err != nil { - return nil, err - } - - out := result.(*getTokenOutput) - out.ResultMetadata = metadata - return out, nil -} - -type getTokenInput struct { - TokenTTL time.Duration -} - -type getTokenOutput struct { - Token string - TokenTTL time.Duration - - ResultMetadata middleware.Metadata -} - -func addGetTokenMiddleware(stack *middleware.Stack, options Options) error { - err := addRequestMiddleware(stack, - options, - "PUT", - "GetToken", - buildGetTokenPath, - buildGetTokenOutput) - if err != nil { - return err - } - - err = stack.Serialize.Add(&tokenTTLRequestHeader{}, middleware.After) - if err != nil { - return err - } - - return nil -} - -func buildGetTokenPath(interface{}) (string, error) { - return getTokenPath, nil -} - -func buildGetTokenOutput(resp *smithyhttp.Response) (v interface{}, err error) { - defer func() { - closeErr := resp.Body.Close() - if err == nil { - err = closeErr - } else if closeErr != nil { - err = fmt.Errorf("response body close error: %v, original error: %w", closeErr, err) - } - }() - - ttlHeader := resp.Header.Get(tokenTTLHeader) - tokenTTL, err := strconv.ParseInt(ttlHeader, 10, 64) - if err != nil { - return nil, fmt.Errorf("unable to parse API token, %w", err) - } - - var token strings.Builder - if _, err = io.Copy(&token, resp.Body); err != nil { - return nil, fmt.Errorf("unable to read API token, %w", err) - } - - return &getTokenOutput{ - Token: token.String(), - TokenTTL: time.Duration(tokenTTL) * time.Second, - }, nil -} - -type tokenTTLRequestHeader struct{} - -func (*tokenTTLRequestHeader) ID() string { return "tokenTTLRequestHeader" } -func (*tokenTTLRequestHeader) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("expect HTTP transport, got %T", in.Request) - } - - input, ok := in.Parameters.(*getTokenInput) - if !ok { - return out, metadata, fmt.Errorf("expect getTokenInput, got %T", in.Parameters) - } - - req.Header.Set(tokenTTLHeader, strconv.Itoa(int(input.TokenTTL/time.Second))) - - return next.HandleSerialize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetUserData.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetUserData.go deleted file mode 100644 index 8903697..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetUserData.go +++ /dev/null @@ -1,61 +0,0 @@ -package imds - -import ( - "context" - "io" - - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -const getUserDataPath = "/latest/user-data" - -// GetUserData uses the path provided to request information from the EC2 -// instance metadata service for dynamic data. The content will be returned -// as a string, or error if the request failed. -func (c *Client) GetUserData(ctx context.Context, params *GetUserDataInput, optFns ...func(*Options)) (*GetUserDataOutput, error) { - if params == nil { - params = &GetUserDataInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetUserData", params, optFns, - addGetUserDataMiddleware, - ) - if err != nil { - return nil, err - } - - out := result.(*GetUserDataOutput) - out.ResultMetadata = metadata - return out, nil -} - -// GetUserDataInput provides the input parameters for the GetUserData -// operation. -type GetUserDataInput struct{} - -// GetUserDataOutput provides the output parameters for the GetUserData -// operation. -type GetUserDataOutput struct { - Content io.ReadCloser - - ResultMetadata middleware.Metadata -} - -func addGetUserDataMiddleware(stack *middleware.Stack, options Options) error { - return addAPIRequestMiddleware(stack, - options, - "GetUserData", - buildGetUserDataPath, - buildGetUserDataOutput) -} - -func buildGetUserDataPath(params interface{}) (string, error) { - return getUserDataPath, nil -} - -func buildGetUserDataOutput(resp *smithyhttp.Response) (interface{}, error) { - return &GetUserDataOutput{ - Content: resp.Body, - }, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/auth.go deleted file mode 100644 index ad283cf..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/auth.go +++ /dev/null @@ -1,48 +0,0 @@ -package imds - -import ( - "context" - "github.com/aws/smithy-go/middleware" -) - -type getIdentityMiddleware struct { - options Options -} - -func (*getIdentityMiddleware) ID() string { - return "GetIdentity" -} - -func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - return next.HandleFinalize(ctx, in) -} - -type signRequestMiddleware struct { -} - -func (*signRequestMiddleware) ID() string { - return "Signing" -} - -func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - return next.HandleFinalize(ctx, in) -} - -type resolveAuthSchemeMiddleware struct { - operation string - options Options -} - -func (*resolveAuthSchemeMiddleware) ID() string { - return "ResolveAuthScheme" -} - -func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/doc.go deleted file mode 100644 index d5765c3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -// Package imds provides the API client for interacting with the Amazon EC2 -// Instance Metadata Service. -// -// All Client operation calls have a default timeout. If the operation is not -// completed before this timeout expires, the operation will be canceled. This -// timeout can be overridden through the following: -// - Set the options flag DisableDefaultTimeout -// - Provide a Context with a timeout or deadline with calling the client's operations. -// -// See the EC2 IMDS user guide for more information on using the API. -// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html -package imds diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/endpoints.go deleted file mode 100644 index d7540da..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/endpoints.go +++ /dev/null @@ -1,20 +0,0 @@ -package imds - -import ( - "context" - "github.com/aws/smithy-go/middleware" -) - -type resolveEndpointV2Middleware struct { - options Options -} - -func (*resolveEndpointV2Middleware) ID() string { - return "ResolveEndpointV2" -} - -func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go deleted file mode 100644 index 94f576a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package imds - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.16.27" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/internal/config/resolvers.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/internal/config/resolvers.go deleted file mode 100644 index ce77455..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/internal/config/resolvers.go +++ /dev/null @@ -1,114 +0,0 @@ -package config - -import ( - "fmt" - "strings" -) - -// ClientEnableState provides an enumeration if the client is enabled, -// disabled, or default behavior. -type ClientEnableState uint - -// Enumeration values for ClientEnableState -const ( - ClientDefaultEnableState ClientEnableState = iota - ClientDisabled - ClientEnabled -) - -// EndpointModeState is the EC2 IMDS Endpoint Configuration Mode -type EndpointModeState uint - -// Enumeration values for ClientEnableState -const ( - EndpointModeStateUnset EndpointModeState = iota - EndpointModeStateIPv4 - EndpointModeStateIPv6 -) - -// SetFromString sets the EndpointModeState based on the provided string value. Unknown values will default to EndpointModeStateUnset -func (e *EndpointModeState) SetFromString(v string) error { - v = strings.TrimSpace(v) - - switch { - case len(v) == 0: - *e = EndpointModeStateUnset - case strings.EqualFold(v, "IPv6"): - *e = EndpointModeStateIPv6 - case strings.EqualFold(v, "IPv4"): - *e = EndpointModeStateIPv4 - default: - return fmt.Errorf("unknown EC2 IMDS endpoint mode, must be either IPv6 or IPv4") - } - return nil -} - -// ClientEnableStateResolver is a config resolver interface for retrieving whether the IMDS client is disabled. -type ClientEnableStateResolver interface { - GetEC2IMDSClientEnableState() (ClientEnableState, bool, error) -} - -// EndpointModeResolver is a config resolver interface for retrieving the EndpointModeState configuration. -type EndpointModeResolver interface { - GetEC2IMDSEndpointMode() (EndpointModeState, bool, error) -} - -// EndpointResolver is a config resolver interface for retrieving the endpoint. -type EndpointResolver interface { - GetEC2IMDSEndpoint() (string, bool, error) -} - -type v1FallbackDisabledResolver interface { - GetEC2IMDSV1FallbackDisabled() (bool, bool) -} - -// ResolveClientEnableState resolves the ClientEnableState from a list of configuration sources. -func ResolveClientEnableState(sources []interface{}) (value ClientEnableState, found bool, err error) { - for _, source := range sources { - if resolver, ok := source.(ClientEnableStateResolver); ok { - value, found, err = resolver.GetEC2IMDSClientEnableState() - if err != nil || found { - return value, found, err - } - } - } - return value, found, err -} - -// ResolveEndpointModeConfig resolves the EndpointModeState from a list of configuration sources. -func ResolveEndpointModeConfig(sources []interface{}) (value EndpointModeState, found bool, err error) { - for _, source := range sources { - if resolver, ok := source.(EndpointModeResolver); ok { - value, found, err = resolver.GetEC2IMDSEndpointMode() - if err != nil || found { - return value, found, err - } - } - } - return value, found, err -} - -// ResolveEndpointConfig resolves the endpoint from a list of configuration sources. -func ResolveEndpointConfig(sources []interface{}) (value string, found bool, err error) { - for _, source := range sources { - if resolver, ok := source.(EndpointResolver); ok { - value, found, err = resolver.GetEC2IMDSEndpoint() - if err != nil || found { - return value, found, err - } - } - } - return value, found, err -} - -// ResolveV1FallbackDisabled ... -func ResolveV1FallbackDisabled(sources []interface{}) (bool, bool) { - for _, source := range sources { - if resolver, ok := source.(v1FallbackDisabledResolver); ok { - if v, found := resolver.GetEC2IMDSV1FallbackDisabled(); found { - return v, true - } - } - } - return false, false -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/request_middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/request_middleware.go deleted file mode 100644 index 90cf4ae..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/request_middleware.go +++ /dev/null @@ -1,313 +0,0 @@ -package imds - -import ( - "bytes" - "context" - "fmt" - "io/ioutil" - "net/url" - "path" - "time" - - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/retry" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -func addAPIRequestMiddleware(stack *middleware.Stack, - options Options, - operation string, - getPath func(interface{}) (string, error), - getOutput func(*smithyhttp.Response) (interface{}, error), -) (err error) { - err = addRequestMiddleware(stack, options, "GET", operation, getPath, getOutput) - if err != nil { - return err - } - - // Token Serializer build and state management. - if !options.disableAPIToken { - err = stack.Finalize.Insert(options.tokenProvider, (*retry.Attempt)(nil).ID(), middleware.After) - if err != nil { - return err - } - - err = stack.Deserialize.Insert(options.tokenProvider, "OperationDeserializer", middleware.Before) - if err != nil { - return err - } - } - - return nil -} - -func addRequestMiddleware(stack *middleware.Stack, - options Options, - method string, - operation string, - getPath func(interface{}) (string, error), - getOutput func(*smithyhttp.Response) (interface{}, error), -) (err error) { - err = awsmiddleware.AddSDKAgentKey(awsmiddleware.FeatureMetadata, "ec2-imds")(stack) - if err != nil { - return err - } - - // Operation timeout - err = stack.Initialize.Add(&operationTimeout{ - Disabled: options.DisableDefaultTimeout, - DefaultTimeout: defaultOperationTimeout, - }, middleware.Before) - if err != nil { - return err - } - - // Operation Serializer - err = stack.Serialize.Add(&serializeRequest{ - GetPath: getPath, - Method: method, - }, middleware.After) - if err != nil { - return err - } - - // Operation endpoint resolver - err = stack.Serialize.Insert(&resolveEndpoint{ - Endpoint: options.Endpoint, - EndpointMode: options.EndpointMode, - }, "OperationSerializer", middleware.Before) - if err != nil { - return err - } - - // Operation Deserializer - err = stack.Deserialize.Add(&deserializeResponse{ - GetOutput: getOutput, - }, middleware.After) - if err != nil { - return err - } - - err = stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{ - LogRequest: options.ClientLogMode.IsRequest(), - LogRequestWithBody: options.ClientLogMode.IsRequestWithBody(), - LogResponse: options.ClientLogMode.IsResponse(), - LogResponseWithBody: options.ClientLogMode.IsResponseWithBody(), - }, middleware.After) - if err != nil { - return err - } - - err = addSetLoggerMiddleware(stack, options) - if err != nil { - return err - } - - if err := addProtocolFinalizerMiddlewares(stack, options, operation); err != nil { - return fmt.Errorf("add protocol finalizers: %w", err) - } - - // Retry support - return retry.AddRetryMiddlewares(stack, retry.AddRetryMiddlewaresOptions{ - Retryer: options.Retryer, - LogRetryAttempts: options.ClientLogMode.IsRetries(), - }) -} - -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) -} - -type serializeRequest struct { - GetPath func(interface{}) (string, error) - Method string -} - -func (*serializeRequest) ID() string { - return "OperationSerializer" -} - -func (m *serializeRequest) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - reqPath, err := m.GetPath(in.Parameters) - if err != nil { - return out, metadata, fmt.Errorf("unable to get request URL path, %w", err) - } - - request.Request.URL.Path = reqPath - request.Request.Method = m.Method - - return next.HandleSerialize(ctx, in) -} - -type deserializeResponse struct { - GetOutput func(*smithyhttp.Response) (interface{}, error) -} - -func (*deserializeResponse) ID() string { - return "OperationDeserializer" -} - -func (m *deserializeResponse) HandleDeserialize( - ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - resp, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, fmt.Errorf( - "unexpected transport response type, %T, want %T", out.RawResponse, resp) - } - defer resp.Body.Close() - - // read the full body so that any operation timeouts cleanup will not race - // the body being read. - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return out, metadata, fmt.Errorf("read response body failed, %w", err) - } - resp.Body = ioutil.NopCloser(bytes.NewReader(body)) - - // Anything that's not 200 |< 300 is error - if resp.StatusCode < 200 || resp.StatusCode >= 300 { - return out, metadata, &smithyhttp.ResponseError{ - Response: resp, - Err: fmt.Errorf("request to EC2 IMDS failed"), - } - } - - result, err := m.GetOutput(resp) - if err != nil { - return out, metadata, fmt.Errorf( - "unable to get deserialized result for response, %w", err, - ) - } - out.Result = result - - return out, metadata, err -} - -type resolveEndpoint struct { - Endpoint string - EndpointMode EndpointModeState -} - -func (*resolveEndpoint) ID() string { - return "ResolveEndpoint" -} - -func (m *resolveEndpoint) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - var endpoint string - if len(m.Endpoint) > 0 { - endpoint = m.Endpoint - } else { - switch m.EndpointMode { - case EndpointModeStateIPv6: - endpoint = defaultIPv6Endpoint - case EndpointModeStateIPv4: - fallthrough - case EndpointModeStateUnset: - endpoint = defaultIPv4Endpoint - default: - return out, metadata, fmt.Errorf("unsupported IMDS endpoint mode") - } - } - - req.URL, err = url.Parse(endpoint) - if err != nil { - return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err) - } - - return next.HandleSerialize(ctx, in) -} - -const ( - defaultOperationTimeout = 5 * time.Second -) - -// operationTimeout adds a timeout on the middleware stack if the Context the -// stack was called with does not have a deadline. The next middleware must -// complete before the timeout, or the context will be canceled. -// -// If DefaultTimeout is zero, no default timeout will be used if the Context -// does not have a timeout. -// -// The next middleware must also ensure that any resources that are also -// canceled by the stack's context are completely consumed before returning. -// Otherwise the timeout cleanup will race the resource being consumed -// upstream. -type operationTimeout struct { - Disabled bool - DefaultTimeout time.Duration -} - -func (*operationTimeout) ID() string { return "OperationTimeout" } - -func (m *operationTimeout) HandleInitialize( - ctx context.Context, input middleware.InitializeInput, next middleware.InitializeHandler, -) ( - output middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.Disabled { - return next.HandleInitialize(ctx, input) - } - - if _, ok := ctx.Deadline(); !ok && m.DefaultTimeout != 0 { - var cancelFn func() - ctx, cancelFn = context.WithTimeout(ctx, m.DefaultTimeout) - defer cancelFn() - } - - return next.HandleInitialize(ctx, input) -} - -// appendURIPath joins a URI path component to the existing path with `/` -// separators between the path components. If the path being added ends with a -// trailing `/` that slash will be maintained. -func appendURIPath(base, add string) string { - reqPath := path.Join(base, add) - if len(add) != 0 && add[len(add)-1] == '/' { - reqPath += "/" - } - return reqPath -} - -func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error { - if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil { - return fmt.Errorf("add ResolveAuthScheme: %w", err) - } - if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil { - return fmt.Errorf("add GetIdentity: %w", err) - } - if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil { - return fmt.Errorf("add ResolveEndpointV2: %w", err) - } - if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", middleware.After); err != nil { - return fmt.Errorf("add Signing: %w", err) - } - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/token_provider.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/token_provider.go deleted file mode 100644 index 5703c6e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/token_provider.go +++ /dev/null @@ -1,261 +0,0 @@ -package imds - -import ( - "context" - "errors" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/smithy-go" - "github.com/aws/smithy-go/logging" - "net/http" - "sync" - "sync/atomic" - "time" - - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -const ( - // Headers for Token and TTL - tokenHeader = "x-aws-ec2-metadata-token" - defaultTokenTTL = 5 * time.Minute -) - -type tokenProvider struct { - client *Client - tokenTTL time.Duration - - token *apiToken - tokenMux sync.RWMutex - - disabled uint32 // Atomic updated -} - -func newTokenProvider(client *Client, ttl time.Duration) *tokenProvider { - return &tokenProvider{ - client: client, - tokenTTL: ttl, - } -} - -// apiToken provides the API token used by all operation calls for th EC2 -// Instance metadata service. -type apiToken struct { - token string - expires time.Time -} - -var timeNow = time.Now - -// Expired returns if the token is expired. -func (t *apiToken) Expired() bool { - // Calling Round(0) on the current time will truncate the monotonic reading only. Ensures credential expiry - // time is always based on reported wall-clock time. - return timeNow().Round(0).After(t.expires) -} - -func (t *tokenProvider) ID() string { return "APITokenProvider" } - -// HandleFinalize is the finalize stack middleware, that if the token provider is -// enabled, will attempt to add the cached API token to the request. If the API -// token is not cached, it will be retrieved in a separate API call, getToken. -// -// For retry attempts, handler must be added after attempt retryer. -// -// If request for getToken fails the token provider may be disabled from future -// requests, depending on the response status code. -func (t *tokenProvider) HandleFinalize( - ctx context.Context, input middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - if t.fallbackEnabled() && !t.enabled() { - // short-circuits to insecure data flow if token provider is disabled. - return next.HandleFinalize(ctx, input) - } - - req, ok := input.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unexpected transport request type %T", input.Request) - } - - tok, err := t.getToken(ctx) - if err != nil { - // If the error allows the token to downgrade to insecure flow allow that. - var bypassErr *bypassTokenRetrievalError - if errors.As(err, &bypassErr) { - return next.HandleFinalize(ctx, input) - } - - return out, metadata, fmt.Errorf("failed to get API token, %w", err) - } - - req.Header.Set(tokenHeader, tok.token) - - return next.HandleFinalize(ctx, input) -} - -// HandleDeserialize is the deserialize stack middleware for determining if the -// operation the token provider is decorating failed because of a 401 -// unauthorized status code. If the operation failed for that reason the token -// provider needs to be re-enabled so that it can start adding the API token to -// operation calls. -func (t *tokenProvider) HandleDeserialize( - ctx context.Context, input middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, input) - if err == nil { - return out, metadata, err - } - - resp, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, fmt.Errorf("expect HTTP transport, got %T", out.RawResponse) - } - - if resp.StatusCode == http.StatusUnauthorized { // unauthorized - t.enable() - err = &retryableError{Err: err, isRetryable: true} - } - - return out, metadata, err -} - -func (t *tokenProvider) getToken(ctx context.Context) (tok *apiToken, err error) { - if t.fallbackEnabled() && !t.enabled() { - return nil, &bypassTokenRetrievalError{ - Err: fmt.Errorf("cannot get API token, provider disabled"), - } - } - - t.tokenMux.RLock() - tok = t.token - t.tokenMux.RUnlock() - - if tok != nil && !tok.Expired() { - return tok, nil - } - - tok, err = t.updateToken(ctx) - if err != nil { - return nil, err - } - - return tok, nil -} - -func (t *tokenProvider) updateToken(ctx context.Context) (*apiToken, error) { - t.tokenMux.Lock() - defer t.tokenMux.Unlock() - - // Prevent multiple requests to update retrieving the token. - if t.token != nil && !t.token.Expired() { - tok := t.token - return tok, nil - } - - result, err := t.client.getToken(ctx, &getTokenInput{ - TokenTTL: t.tokenTTL, - }) - if err != nil { - var statusErr interface{ HTTPStatusCode() int } - if errors.As(err, &statusErr) { - switch statusErr.HTTPStatusCode() { - // Disable future get token if failed because of 403, 404, or 405 - case http.StatusForbidden, - http.StatusNotFound, - http.StatusMethodNotAllowed: - - if t.fallbackEnabled() { - logger := middleware.GetLogger(ctx) - logger.Logf(logging.Warn, "falling back to IMDSv1: %v", err) - t.disable() - } - - // 400 errors are terminal, and need to be upstreamed - case http.StatusBadRequest: - return nil, err - } - } - - // Disable if request send failed or timed out getting response - var re *smithyhttp.RequestSendError - var ce *smithy.CanceledError - if errors.As(err, &re) || errors.As(err, &ce) { - atomic.StoreUint32(&t.disabled, 1) - } - - if !t.fallbackEnabled() { - // NOTE: getToken() is an implementation detail of some outer operation - // (e.g. GetMetadata). It has its own retries that have already been exhausted. - // Mark the underlying error as a terminal error. - err = &retryableError{Err: err, isRetryable: false} - return nil, err - } - - // Token couldn't be retrieved, fallback to IMDSv1 insecure flow for this request - // and allow the request to proceed. Future requests _may_ re-attempt fetching a - // token if not disabled. - return nil, &bypassTokenRetrievalError{Err: err} - } - - tok := &apiToken{ - token: result.Token, - expires: timeNow().Add(result.TokenTTL), - } - t.token = tok - - return tok, nil -} - -// enabled returns if the token provider is current enabled or not. -func (t *tokenProvider) enabled() bool { - return atomic.LoadUint32(&t.disabled) == 0 -} - -// fallbackEnabled returns false if EnableFallback is [aws.FalseTernary], true otherwise -func (t *tokenProvider) fallbackEnabled() bool { - switch t.client.options.EnableFallback { - case aws.FalseTernary: - return false - default: - return true - } -} - -// disable disables the token provider and it will no longer attempt to inject -// the token, nor request updates. -func (t *tokenProvider) disable() { - atomic.StoreUint32(&t.disabled, 1) -} - -// enable enables the token provide to start refreshing tokens, and adding them -// to the pending request. -func (t *tokenProvider) enable() { - t.tokenMux.Lock() - t.token = nil - t.tokenMux.Unlock() - atomic.StoreUint32(&t.disabled, 0) -} - -type bypassTokenRetrievalError struct { - Err error -} - -func (e *bypassTokenRetrievalError) Error() string { - return fmt.Sprintf("bypass token retrieval, %v", e.Err) -} - -func (e *bypassTokenRetrievalError) Unwrap() error { return e.Err } - -type retryableError struct { - Err error - isRetryable bool -} - -func (e *retryableError) RetryableError() bool { return e.isRetryable } - -func (e *retryableError) Error() string { return e.Err.Error() } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/auth.go deleted file mode 100644 index 0b81db5..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/auth.go +++ /dev/null @@ -1,45 +0,0 @@ -package auth - -import ( - "github.com/aws/smithy-go/auth" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// HTTPAuthScheme is the SDK's internal implementation of smithyhttp.AuthScheme -// for pre-existing implementations where the signer was added to client -// config. SDK clients will key off of this type and ensure per-operation -// updates to those signers persist on the scheme itself. -type HTTPAuthScheme struct { - schemeID string - signer smithyhttp.Signer -} - -var _ smithyhttp.AuthScheme = (*HTTPAuthScheme)(nil) - -// NewHTTPAuthScheme returns an auth scheme instance with the given config. -func NewHTTPAuthScheme(schemeID string, signer smithyhttp.Signer) *HTTPAuthScheme { - return &HTTPAuthScheme{ - schemeID: schemeID, - signer: signer, - } -} - -// SchemeID identifies the auth scheme. -func (s *HTTPAuthScheme) SchemeID() string { - return s.schemeID -} - -// IdentityResolver gets the identity resolver for the auth scheme. -func (s *HTTPAuthScheme) IdentityResolver(o auth.IdentityResolverOptions) auth.IdentityResolver { - return o.GetIdentityResolver(s.schemeID) -} - -// Signer gets the signer for the auth scheme. -func (s *HTTPAuthScheme) Signer() smithyhttp.Signer { - return s.signer -} - -// WithSigner returns a new instance of the auth scheme with the updated signer. -func (s *HTTPAuthScheme) WithSigner(signer smithyhttp.Signer) *HTTPAuthScheme { - return NewHTTPAuthScheme(s.schemeID, signer) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/scheme.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/scheme.go deleted file mode 100644 index bbc2ec0..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/scheme.go +++ /dev/null @@ -1,191 +0,0 @@ -package auth - -import ( - "context" - "fmt" - - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/middleware" -) - -// SigV4 is a constant representing -// Authentication Scheme Signature Version 4 -const SigV4 = "sigv4" - -// SigV4A is a constant representing -// Authentication Scheme Signature Version 4A -const SigV4A = "sigv4a" - -// SigV4S3Express identifies the S3 S3Express auth scheme. -const SigV4S3Express = "sigv4-s3express" - -// None is a constant representing the -// None Authentication Scheme -const None = "none" - -// SupportedSchemes is a data structure -// that indicates the list of supported AWS -// authentication schemes -var SupportedSchemes = map[string]bool{ - SigV4: true, - SigV4A: true, - SigV4S3Express: true, - None: true, -} - -// AuthenticationScheme is a representation of -// AWS authentication schemes -type AuthenticationScheme interface { - isAuthenticationScheme() -} - -// AuthenticationSchemeV4 is a AWS SigV4 representation -type AuthenticationSchemeV4 struct { - Name string - SigningName *string - SigningRegion *string - DisableDoubleEncoding *bool -} - -func (a *AuthenticationSchemeV4) isAuthenticationScheme() {} - -// AuthenticationSchemeV4A is a AWS SigV4A representation -type AuthenticationSchemeV4A struct { - Name string - SigningName *string - SigningRegionSet []string - DisableDoubleEncoding *bool -} - -func (a *AuthenticationSchemeV4A) isAuthenticationScheme() {} - -// AuthenticationSchemeNone is a representation for the none auth scheme -type AuthenticationSchemeNone struct{} - -func (a *AuthenticationSchemeNone) isAuthenticationScheme() {} - -// NoAuthenticationSchemesFoundError is used in signaling -// that no authentication schemes have been specified. -type NoAuthenticationSchemesFoundError struct{} - -func (e *NoAuthenticationSchemesFoundError) Error() string { - return fmt.Sprint("No authentication schemes specified.") -} - -// UnSupportedAuthenticationSchemeSpecifiedError is used in -// signaling that only unsupported authentication schemes -// were specified. -type UnSupportedAuthenticationSchemeSpecifiedError struct { - UnsupportedSchemes []string -} - -func (e *UnSupportedAuthenticationSchemeSpecifiedError) Error() string { - return fmt.Sprint("Unsupported authentication scheme specified.") -} - -// GetAuthenticationSchemes extracts the relevant authentication scheme data -// into a custom strongly typed Go data structure. -func GetAuthenticationSchemes(p *smithy.Properties) ([]AuthenticationScheme, error) { - var result []AuthenticationScheme - if !p.Has("authSchemes") { - return nil, &NoAuthenticationSchemesFoundError{} - } - - authSchemes, _ := p.Get("authSchemes").([]interface{}) - - var unsupportedSchemes []string - for _, scheme := range authSchemes { - authScheme, _ := scheme.(map[string]interface{}) - - version := authScheme["name"].(string) - switch version { - case SigV4, SigV4S3Express: - v4Scheme := AuthenticationSchemeV4{ - Name: version, - SigningName: getSigningName(authScheme), - SigningRegion: getSigningRegion(authScheme), - DisableDoubleEncoding: getDisableDoubleEncoding(authScheme), - } - result = append(result, AuthenticationScheme(&v4Scheme)) - case SigV4A: - v4aScheme := AuthenticationSchemeV4A{ - Name: SigV4A, - SigningName: getSigningName(authScheme), - SigningRegionSet: getSigningRegionSet(authScheme), - DisableDoubleEncoding: getDisableDoubleEncoding(authScheme), - } - result = append(result, AuthenticationScheme(&v4aScheme)) - case None: - noneScheme := AuthenticationSchemeNone{} - result = append(result, AuthenticationScheme(&noneScheme)) - default: - unsupportedSchemes = append(unsupportedSchemes, authScheme["name"].(string)) - continue - } - } - - if len(result) == 0 { - return nil, &UnSupportedAuthenticationSchemeSpecifiedError{ - UnsupportedSchemes: unsupportedSchemes, - } - } - - return result, nil -} - -type disableDoubleEncoding struct{} - -// SetDisableDoubleEncoding sets or modifies the disable double encoding option -// on the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func SetDisableDoubleEncoding(ctx context.Context, value bool) context.Context { - return middleware.WithStackValue(ctx, disableDoubleEncoding{}, value) -} - -// GetDisableDoubleEncoding retrieves the disable double encoding option -// from the context. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func GetDisableDoubleEncoding(ctx context.Context) (value bool, ok bool) { - value, ok = middleware.GetStackValue(ctx, disableDoubleEncoding{}).(bool) - return value, ok -} - -func getSigningName(authScheme map[string]interface{}) *string { - signingName, ok := authScheme["signingName"].(string) - if !ok || signingName == "" { - return nil - } - return &signingName -} - -func getSigningRegionSet(authScheme map[string]interface{}) []string { - untypedSigningRegionSet, ok := authScheme["signingRegionSet"].([]interface{}) - if !ok { - return nil - } - signingRegionSet := []string{} - for _, item := range untypedSigningRegionSet { - signingRegionSet = append(signingRegionSet, item.(string)) - } - return signingRegionSet -} - -func getSigningRegion(authScheme map[string]interface{}) *string { - signingRegion, ok := authScheme["signingRegion"].(string) - if !ok || signingRegion == "" { - return nil - } - return &signingRegion -} - -func getDisableDoubleEncoding(authScheme map[string]interface{}) *bool { - disableDoubleEncoding, ok := authScheme["disableDoubleEncoding"].(bool) - if !ok { - return nil - } - return &disableDoubleEncoding -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/bearer_token_adapter.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/bearer_token_adapter.go deleted file mode 100644 index f059b5d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/bearer_token_adapter.go +++ /dev/null @@ -1,43 +0,0 @@ -package smithy - -import ( - "context" - "fmt" - "time" - - "github.com/aws/smithy-go" - "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/auth/bearer" -) - -// BearerTokenAdapter adapts smithy bearer.Token to smithy auth.Identity. -type BearerTokenAdapter struct { - Token bearer.Token -} - -var _ auth.Identity = (*BearerTokenAdapter)(nil) - -// Expiration returns the time of expiration for the token. -func (v *BearerTokenAdapter) Expiration() time.Time { - return v.Token.Expires -} - -// BearerTokenProviderAdapter adapts smithy bearer.TokenProvider to smithy -// auth.IdentityResolver. -type BearerTokenProviderAdapter struct { - Provider bearer.TokenProvider -} - -var _ (auth.IdentityResolver) = (*BearerTokenProviderAdapter)(nil) - -// GetIdentity retrieves a bearer token using the underlying provider. -func (v *BearerTokenProviderAdapter) GetIdentity(ctx context.Context, _ smithy.Properties) ( - auth.Identity, error, -) { - token, err := v.Provider.RetrieveBearerToken(ctx) - if err != nil { - return nil, fmt.Errorf("get token: %w", err) - } - - return &BearerTokenAdapter{Token: token}, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/bearer_token_signer_adapter.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/bearer_token_signer_adapter.go deleted file mode 100644 index a882815..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/bearer_token_signer_adapter.go +++ /dev/null @@ -1,35 +0,0 @@ -package smithy - -import ( - "context" - "fmt" - - "github.com/aws/smithy-go" - "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/auth/bearer" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// BearerTokenSignerAdapter adapts smithy bearer.Signer to smithy http -// auth.Signer. -type BearerTokenSignerAdapter struct { - Signer bearer.Signer -} - -var _ (smithyhttp.Signer) = (*BearerTokenSignerAdapter)(nil) - -// SignRequest signs the request with the provided bearer token. -func (v *BearerTokenSignerAdapter) SignRequest(ctx context.Context, r *smithyhttp.Request, identity auth.Identity, _ smithy.Properties) error { - ca, ok := identity.(*BearerTokenAdapter) - if !ok { - return fmt.Errorf("unexpected identity type: %T", identity) - } - - signed, err := v.Signer.SignWithBearerToken(ctx, ca.Token, r) - if err != nil { - return fmt.Errorf("sign request: %w", err) - } - - *r = *signed.(*smithyhttp.Request) - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/credentials_adapter.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/credentials_adapter.go deleted file mode 100644 index f926c4a..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/credentials_adapter.go +++ /dev/null @@ -1,46 +0,0 @@ -package smithy - -import ( - "context" - "fmt" - "time" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/smithy-go" - "github.com/aws/smithy-go/auth" -) - -// CredentialsAdapter adapts aws.Credentials to auth.Identity. -type CredentialsAdapter struct { - Credentials aws.Credentials -} - -var _ auth.Identity = (*CredentialsAdapter)(nil) - -// Expiration returns the time of expiration for the credentials. -func (v *CredentialsAdapter) Expiration() time.Time { - return v.Credentials.Expires -} - -// CredentialsProviderAdapter adapts aws.CredentialsProvider to auth.IdentityResolver. -type CredentialsProviderAdapter struct { - Provider aws.CredentialsProvider -} - -var _ (auth.IdentityResolver) = (*CredentialsProviderAdapter)(nil) - -// GetIdentity retrieves AWS credentials using the underlying provider. -func (v *CredentialsProviderAdapter) GetIdentity(ctx context.Context, _ smithy.Properties) ( - auth.Identity, error, -) { - if v.Provider == nil { - return &CredentialsAdapter{Credentials: aws.Credentials{}}, nil - } - - creds, err := v.Provider.Retrieve(ctx) - if err != nil { - return nil, fmt.Errorf("get credentials: %w", err) - } - - return &CredentialsAdapter{Credentials: creds}, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/smithy.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/smithy.go deleted file mode 100644 index 42b4586..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/smithy.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package smithy adapts concrete AWS auth and signing types to the generic smithy versions. -package smithy diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/v4signer_adapter.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/v4signer_adapter.go deleted file mode 100644 index 24db8e1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/v4signer_adapter.go +++ /dev/null @@ -1,57 +0,0 @@ -package smithy - -import ( - "context" - "fmt" - - v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - internalcontext "github.com/aws/aws-sdk-go-v2/internal/context" - "github.com/aws/aws-sdk-go-v2/internal/sdk" - "github.com/aws/smithy-go" - "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/logging" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// V4SignerAdapter adapts v4.HTTPSigner to smithy http.Signer. -type V4SignerAdapter struct { - Signer v4.HTTPSigner - Logger logging.Logger - LogSigning bool -} - -var _ (smithyhttp.Signer) = (*V4SignerAdapter)(nil) - -// SignRequest signs the request with the provided identity. -func (v *V4SignerAdapter) SignRequest(ctx context.Context, r *smithyhttp.Request, identity auth.Identity, props smithy.Properties) error { - ca, ok := identity.(*CredentialsAdapter) - if !ok { - return fmt.Errorf("unexpected identity type: %T", identity) - } - - name, ok := smithyhttp.GetSigV4SigningName(&props) - if !ok { - return fmt.Errorf("sigv4 signing name is required") - } - - region, ok := smithyhttp.GetSigV4SigningRegion(&props) - if !ok { - return fmt.Errorf("sigv4 signing region is required") - } - - hash := v4.GetPayloadHash(ctx) - signingTime := sdk.NowTime() - skew := internalcontext.GetAttemptSkewContext(ctx) - signingTime = signingTime.Add(skew) - err := v.Signer.SignHTTP(ctx, ca.Credentials, r.Request, hash, name, region, signingTime, func(o *v4.SignerOptions) { - o.DisableURIPathEscaping, _ = smithyhttp.GetDisableDoubleEncoding(&props) - - o.Logger = v.Logger - o.LogSigning = v.LogSigning - }) - if err != nil { - return fmt.Errorf("sign http: %w", err) - } - - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md deleted file mode 100644 index 6ffdf06..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md +++ /dev/null @@ -1,486 +0,0 @@ -# v1.4.16 (2025-12-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.15 (2025-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. - -# v1.4.14 (2025-11-19.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.13 (2025-11-04) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. - -# v1.4.12 (2025-10-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.11 (2025-10-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.10 (2025-10-16) - -* **Dependency Update**: Bump minimum Go version to 1.23. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.9 (2025-09-26) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.8 (2025-09-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.7 (2025-09-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.6 (2025-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.5 (2025-08-27) - -* **Dependency Update**: Update to smithy-go v1.23.0. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.4 (2025-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.3 (2025-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.2 (2025-08-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.1 (2025-07-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.0 (2025-07-28) - -* **Feature**: Add support for HTTP interceptors. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.37 (2025-07-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.36 (2025-06-17) - -* **Dependency Update**: Update to smithy-go v1.22.4. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.35 (2025-06-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.34 (2025-02-27) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.33 (2025-02-18) - -* **Bug Fix**: Bump go version to 1.22 -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.32 (2025-02-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.31 (2025-01-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.30 (2025-01-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.29 (2025-01-24) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v1.3.28 (2025-01-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.27 (2025-01-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.26 (2024-12-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.25 (2024-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.24 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.23 (2024-11-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.22 (2024-10-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.21 (2024-10-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.20 (2024-10-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.19 (2024-10-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.18 (2024-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.17 (2024-09-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.16 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.15 (2024-07-10.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.14 (2024-07-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.13 (2024-06-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.12 (2024-06-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.11 (2024-06-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.10 (2024-06-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.9 (2024-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.8 (2024-06-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.7 (2024-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.6 (2024-05-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.5 (2024-03-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.4 (2024-03-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.3 (2024-03-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.2 (2024-02-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.1 (2024-02-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.10 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.9 (2023-12-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.8 (2023-12-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.7 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.6 (2023-11-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.5 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.4 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.3 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.2 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.1 (2023-11-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.43 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.42 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.41 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.40 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.39 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.38 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.37 (2023-07-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.36 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.35 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.34 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.33 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.32 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.31 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.30 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.29 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.28 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.27 (2022-12-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.26 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.25 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.24 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.23 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.22 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.21 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.20 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.19 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.18 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.17 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.16 (2022-08-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.15 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.14 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.13 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.12 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.11 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.10 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.9 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.8 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.7 (2022-03-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.6 (2022-03-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.5 (2022-02-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.4 (2022-01-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.3 (2022-01-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.2 (2021-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.1 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.0 (2021-11-06) - -* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.0.7 (2021-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.0.6 (2021-10-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.0.5 (2021-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.0.4 (2021-08-27) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.0.3 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.0.2 (2021-08-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.0.1 (2021-07-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.0.0 (2021-06-25) - -* **Release**: Release new modules -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/config.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/config.go deleted file mode 100644 index cd4d19b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/config.go +++ /dev/null @@ -1,65 +0,0 @@ -package configsources - -import ( - "context" - "github.com/aws/aws-sdk-go-v2/aws" -) - -// EnableEndpointDiscoveryProvider is an interface for retrieving external configuration value -// for Enable Endpoint Discovery -type EnableEndpointDiscoveryProvider interface { - GetEnableEndpointDiscovery(ctx context.Context) (value aws.EndpointDiscoveryEnableState, found bool, err error) -} - -// ResolveEnableEndpointDiscovery extracts the first instance of a EnableEndpointDiscoveryProvider from the config slice. -// Additionally returns a aws.EndpointDiscoveryEnableState to indicate if the value was found in provided configs, -// and error if one is encountered. -func ResolveEnableEndpointDiscovery(ctx context.Context, configs []interface{}) (value aws.EndpointDiscoveryEnableState, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(EnableEndpointDiscoveryProvider); ok { - value, found, err = p.GetEnableEndpointDiscovery(ctx) - if err != nil || found { - break - } - } - } - return -} - -// UseDualStackEndpointProvider is an interface for retrieving external configuration values for UseDualStackEndpoint -type UseDualStackEndpointProvider interface { - GetUseDualStackEndpoint(context.Context) (value aws.DualStackEndpointState, found bool, err error) -} - -// ResolveUseDualStackEndpoint extracts the first instance of a UseDualStackEndpoint from the config slice. -// Additionally returns a boolean to indicate if the value was found in provided configs, and error if one is encountered. -func ResolveUseDualStackEndpoint(ctx context.Context, configs []interface{}) (value aws.DualStackEndpointState, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(UseDualStackEndpointProvider); ok { - value, found, err = p.GetUseDualStackEndpoint(ctx) - if err != nil || found { - break - } - } - } - return -} - -// UseFIPSEndpointProvider is an interface for retrieving external configuration values for UseFIPSEndpoint -type UseFIPSEndpointProvider interface { - GetUseFIPSEndpoint(context.Context) (value aws.FIPSEndpointState, found bool, err error) -} - -// ResolveUseFIPSEndpoint extracts the first instance of a UseFIPSEndpointProvider from the config slice. -// Additionally, returns a boolean to indicate if the value was found in provided configs, and error if one is encountered. -func ResolveUseFIPSEndpoint(ctx context.Context, configs []interface{}) (value aws.FIPSEndpointState, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(UseFIPSEndpointProvider); ok { - value, found, err = p.GetUseFIPSEndpoint(ctx) - if err != nil || found { - break - } - } - } - return -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/endpoints.go deleted file mode 100644 index e7835f8..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/endpoints.go +++ /dev/null @@ -1,57 +0,0 @@ -package configsources - -import ( - "context" -) - -// ServiceBaseEndpointProvider is needed to search for all providers -// that provide a configured service endpoint -type ServiceBaseEndpointProvider interface { - GetServiceBaseEndpoint(ctx context.Context, sdkID string) (string, bool, error) -} - -// IgnoreConfiguredEndpointsProvider is needed to search for all providers -// that provide a flag to disable configured endpoints. -// -// Currently duplicated from github.com/aws/aws-sdk-go-v2/config because -// service packages cannot import github.com/aws/aws-sdk-go-v2/config -// due to result import cycle error. -type IgnoreConfiguredEndpointsProvider interface { - GetIgnoreConfiguredEndpoints(ctx context.Context) (bool, bool, error) -} - -// GetIgnoreConfiguredEndpoints is used in knowing when to disable configured -// endpoints feature. -// -// Currently duplicated from github.com/aws/aws-sdk-go-v2/config because -// service packages cannot import github.com/aws/aws-sdk-go-v2/config -// due to result import cycle error. -func GetIgnoreConfiguredEndpoints(ctx context.Context, configs []interface{}) (value bool, found bool, err error) { - for _, cfg := range configs { - if p, ok := cfg.(IgnoreConfiguredEndpointsProvider); ok { - value, found, err = p.GetIgnoreConfiguredEndpoints(ctx) - if err != nil || found { - break - } - } - } - return -} - -// ResolveServiceBaseEndpoint is used to retrieve service endpoints from configured sources -// while allowing for configured endpoints to be disabled -func ResolveServiceBaseEndpoint(ctx context.Context, sdkID string, configs []interface{}) (value string, found bool, err error) { - if val, found, _ := GetIgnoreConfiguredEndpoints(ctx, configs); found && val { - return "", false, nil - } - - for _, cs := range configs { - if p, ok := cs.(ServiceBaseEndpointProvider); ok { - value, found, err = p.GetServiceBaseEndpoint(context.Background(), sdkID) - if err != nil || found { - break - } - } - } - return -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go deleted file mode 100644 index 72df7b8..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package configsources - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.4.16" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/context/context.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/context/context.go deleted file mode 100644 index f0c283d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/context/context.go +++ /dev/null @@ -1,52 +0,0 @@ -package context - -import ( - "context" - "time" - - "github.com/aws/smithy-go/middleware" -) - -type s3BackendKey struct{} -type checksumInputAlgorithmKey struct{} -type clockSkew struct{} - -const ( - // S3BackendS3Express identifies the S3Express backend - S3BackendS3Express = "S3Express" -) - -// SetS3Backend stores the resolved endpoint backend within the request -// context, which is required for a variety of custom S3 behaviors. -func SetS3Backend(ctx context.Context, typ string) context.Context { - return middleware.WithStackValue(ctx, s3BackendKey{}, typ) -} - -// GetS3Backend retrieves the stored endpoint backend within the context. -func GetS3Backend(ctx context.Context) string { - v, _ := middleware.GetStackValue(ctx, s3BackendKey{}).(string) - return v -} - -// SetChecksumInputAlgorithm sets the request checksum algorithm on the -// context. -func SetChecksumInputAlgorithm(ctx context.Context, value string) context.Context { - return middleware.WithStackValue(ctx, checksumInputAlgorithmKey{}, value) -} - -// GetChecksumInputAlgorithm returns the checksum algorithm from the context. -func GetChecksumInputAlgorithm(ctx context.Context) string { - v, _ := middleware.GetStackValue(ctx, checksumInputAlgorithmKey{}).(string) - return v -} - -// SetAttemptSkewContext sets the clock skew value on the context -func SetAttemptSkewContext(ctx context.Context, v time.Duration) context.Context { - return middleware.WithStackValue(ctx, clockSkew{}, v) -} - -// GetAttemptSkewContext gets the clock skew value from the context -func GetAttemptSkewContext(ctx context.Context) time.Duration { - x, _ := middleware.GetStackValue(ctx, clockSkew{}).(time.Duration) - return x -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/arn.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/arn.go deleted file mode 100644 index e6223dd..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/arn.go +++ /dev/null @@ -1,94 +0,0 @@ -package awsrulesfn - -import ( - "strings" -) - -// ARN provides AWS ARN components broken out into a data structure. -type ARN struct { - Partition string - Service string - Region string - AccountId string - ResourceId OptionalStringSlice -} - -const ( - arnDelimiters = ":" - resourceDelimiters = "/:" - arnSections = 6 - arnPrefix = "arn:" - - // zero-indexed - sectionPartition = 1 - sectionService = 2 - sectionRegion = 3 - sectionAccountID = 4 - sectionResource = 5 -) - -// ParseARN returns an [ARN] value parsed from the input string provided. If -// the ARN cannot be parsed nil will be returned, and error added to -// [ErrorCollector]. -func ParseARN(input string) *ARN { - if !strings.HasPrefix(input, arnPrefix) { - return nil - } - - sections := strings.SplitN(input, arnDelimiters, arnSections) - if numSections := len(sections); numSections != arnSections { - return nil - } - - if sections[sectionPartition] == "" { - return nil - } - if sections[sectionService] == "" { - return nil - } - if sections[sectionResource] == "" { - return nil - } - - return &ARN{ - Partition: sections[sectionPartition], - Service: sections[sectionService], - Region: sections[sectionRegion], - AccountId: sections[sectionAccountID], - ResourceId: splitResource(sections[sectionResource]), - } -} - -// splitResource splits the resource components by the ARN resource delimiters. -func splitResource(v string) []string { - var parts []string - var offset int - - for offset <= len(v) { - idx := strings.IndexAny(v[offset:], "/:") - if idx < 0 { - parts = append(parts, v[offset:]) - break - } - parts = append(parts, v[offset:idx+offset]) - offset += idx + 1 - } - - return parts -} - -// OptionalStringSlice provides a helper to safely get the index of a string -// slice that may be out of bounds. Returns pointer to string if index is -// valid. Otherwise returns nil. -type OptionalStringSlice []string - -// Get returns a string pointer of the string at index i if the index is valid. -// Otherwise returns nil. -func (s OptionalStringSlice) Get(i int) *string { - if i < 0 || i >= len(s) { - return nil - } - - v := s[i] - return &v -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/doc.go deleted file mode 100644 index d5a3658..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package awsrulesfn provides AWS focused endpoint rule functions for -// evaluating endpoint resolution rules. -package awsrulesfn diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/generate.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/generate.go deleted file mode 100644 index df72da9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/generate.go +++ /dev/null @@ -1,7 +0,0 @@ -//go:build codegen -// +build codegen - -package awsrulesfn - -//go:generate go run -tags codegen ./internal/partition/codegen.go -model partitions.json -output partitions.go -//go:generate gofmt -w -s . diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/host.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/host.go deleted file mode 100644 index 637e5fc..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/host.go +++ /dev/null @@ -1,51 +0,0 @@ -package awsrulesfn - -import ( - "net" - "strings" - - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// IsVirtualHostableS3Bucket returns if the input is a DNS compatible bucket -// name and can be used with Amazon S3 virtual hosted style addressing. Similar -// to [rulesfn.IsValidHostLabel] with the added restriction that the length of label -// must be [3:63] characters long, all lowercase, and not formatted as an IP -// address. -func IsVirtualHostableS3Bucket(input string, allowSubDomains bool) bool { - // input should not be formatted as an IP address - // NOTE: this will technically trip up on IPv6 hosts with zone IDs, but - // validation further down will catch that anyway (it's guaranteed to have - // unfriendly characters % and : if that's the case) - if net.ParseIP(input) != nil { - return false - } - - var labels []string - if allowSubDomains { - labels = strings.Split(input, ".") - } else { - labels = []string{input} - } - - for _, label := range labels { - // validate special length constraints - if l := len(label); l < 3 || l > 63 { - return false - } - - // Validate no capital letters - for _, r := range label { - if r >= 'A' && r <= 'Z' { - return false - } - } - - // Validate valid host label - if !smithyhttp.ValidHostLabel(label) { - return false - } - } - - return true -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partition.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partition.go deleted file mode 100644 index 91414af..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partition.go +++ /dev/null @@ -1,76 +0,0 @@ -package awsrulesfn - -import "regexp" - -// Partition provides the metadata describing an AWS partition. -type Partition struct { - ID string `json:"id"` - Regions map[string]RegionOverrides `json:"regions"` - RegionRegex string `json:"regionRegex"` - DefaultConfig PartitionConfig `json:"outputs"` -} - -// PartitionConfig provides the endpoint metadata for an AWS region or partition. -type PartitionConfig struct { - Name string `json:"name"` - DnsSuffix string `json:"dnsSuffix"` - DualStackDnsSuffix string `json:"dualStackDnsSuffix"` - SupportsFIPS bool `json:"supportsFIPS"` - SupportsDualStack bool `json:"supportsDualStack"` - ImplicitGlobalRegion string `json:"implicitGlobalRegion"` -} - -type RegionOverrides struct { - Name *string `json:"name"` - DnsSuffix *string `json:"dnsSuffix"` - DualStackDnsSuffix *string `json:"dualStackDnsSuffix"` - SupportsFIPS *bool `json:"supportsFIPS"` - SupportsDualStack *bool `json:"supportsDualStack"` -} - -const defaultPartition = "aws" - -func getPartition(partitions []Partition, region string) *PartitionConfig { - for _, partition := range partitions { - if v, ok := partition.Regions[region]; ok { - p := mergeOverrides(partition.DefaultConfig, v) - return &p - } - } - - for _, partition := range partitions { - regionRegex := regexp.MustCompile(partition.RegionRegex) - if regionRegex.MatchString(region) { - v := partition.DefaultConfig - return &v - } - } - - for _, partition := range partitions { - if partition.ID == defaultPartition { - v := partition.DefaultConfig - return &v - } - } - - return nil -} - -func mergeOverrides(into PartitionConfig, from RegionOverrides) PartitionConfig { - if from.Name != nil { - into.Name = *from.Name - } - if from.DnsSuffix != nil { - into.DnsSuffix = *from.DnsSuffix - } - if from.DualStackDnsSuffix != nil { - into.DualStackDnsSuffix = *from.DualStackDnsSuffix - } - if from.SupportsFIPS != nil { - into.SupportsFIPS = *from.SupportsFIPS - } - if from.SupportsDualStack != nil { - into.SupportsDualStack = *from.SupportsDualStack - } - return into -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go deleted file mode 100644 index 6ab4d96..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go +++ /dev/null @@ -1,496 +0,0 @@ -// Code generated by endpoint/awsrulesfn/internal/partition. DO NOT EDIT. - -package awsrulesfn - -// GetPartition returns an AWS [Partition] for the region provided. If the -// partition cannot be determined then the default partition (AWS commercial) -// will be returned. -func GetPartition(region string) *PartitionConfig { - return getPartition(partitions, region) -} - -var partitions = []Partition{ - { - ID: "aws", - RegionRegex: "^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws", - DnsSuffix: "amazonaws.com", - DualStackDnsSuffix: "api.aws", - SupportsFIPS: true, - SupportsDualStack: true, - ImplicitGlobalRegion: "us-east-1", - }, - Regions: map[string]RegionOverrides{ - "af-south-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-east-2": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-northeast-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-northeast-2": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-northeast-3": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-south-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-south-2": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-southeast-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-southeast-2": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-southeast-3": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-southeast-4": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-southeast-5": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-southeast-6": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ap-southeast-7": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "aws-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ca-central-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "ca-west-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "eu-central-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "eu-central-2": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "eu-north-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "eu-south-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "eu-south-2": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "eu-west-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "eu-west-2": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "eu-west-3": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "il-central-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "me-central-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "me-south-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "mx-central-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "sa-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-east-2": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-west-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-west-2": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-cn", - RegionRegex: "^cn\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-cn", - DnsSuffix: "amazonaws.com.cn", - DualStackDnsSuffix: "api.amazonwebservices.com.cn", - SupportsFIPS: true, - SupportsDualStack: true, - ImplicitGlobalRegion: "cn-northwest-1", - }, - Regions: map[string]RegionOverrides{ - "aws-cn-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "cn-north-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "cn-northwest-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-eusc", - RegionRegex: "^eusc\\-(de)\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-eusc", - DnsSuffix: "amazonaws.eu", - DualStackDnsSuffix: "api.amazonwebservices.eu", - SupportsFIPS: true, - SupportsDualStack: true, - ImplicitGlobalRegion: "eusc-de-east-1", - }, - Regions: map[string]RegionOverrides{ - "eusc-de-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-iso", - RegionRegex: "^us\\-iso\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-iso", - DnsSuffix: "c2s.ic.gov", - DualStackDnsSuffix: "api.aws.ic.gov", - SupportsFIPS: true, - SupportsDualStack: true, - ImplicitGlobalRegion: "us-iso-east-1", - }, - Regions: map[string]RegionOverrides{ - "aws-iso-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-iso-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-iso-west-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-iso-b", - RegionRegex: "^us\\-isob\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-iso-b", - DnsSuffix: "sc2s.sgov.gov", - DualStackDnsSuffix: "api.aws.scloud", - SupportsFIPS: true, - SupportsDualStack: true, - ImplicitGlobalRegion: "us-isob-east-1", - }, - Regions: map[string]RegionOverrides{ - "aws-iso-b-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-isob-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-isob-west-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-iso-e", - RegionRegex: "^eu\\-isoe\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-iso-e", - DnsSuffix: "cloud.adc-e.uk", - DualStackDnsSuffix: "api.cloud-aws.adc-e.uk", - SupportsFIPS: true, - SupportsDualStack: true, - ImplicitGlobalRegion: "eu-isoe-west-1", - }, - Regions: map[string]RegionOverrides{ - "aws-iso-e-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "eu-isoe-west-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-iso-f", - RegionRegex: "^us\\-isof\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-iso-f", - DnsSuffix: "csp.hci.ic.gov", - DualStackDnsSuffix: "api.aws.hci.ic.gov", - SupportsFIPS: true, - SupportsDualStack: true, - ImplicitGlobalRegion: "us-isof-south-1", - }, - Regions: map[string]RegionOverrides{ - "aws-iso-f-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-isof-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-isof-south-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, - { - ID: "aws-us-gov", - RegionRegex: "^us\\-gov\\-\\w+\\-\\d+$", - DefaultConfig: PartitionConfig{ - Name: "aws-us-gov", - DnsSuffix: "amazonaws.com", - DualStackDnsSuffix: "api.aws", - SupportsFIPS: true, - SupportsDualStack: true, - ImplicitGlobalRegion: "us-gov-west-1", - }, - Regions: map[string]RegionOverrides{ - "aws-us-gov-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-gov-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-gov-west-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - }, - }, -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json deleted file mode 100644 index c789264..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json +++ /dev/null @@ -1,267 +0,0 @@ -{ - "partitions" : [ { - "id" : "aws", - "outputs" : { - "dnsSuffix" : "amazonaws.com", - "dualStackDnsSuffix" : "api.aws", - "implicitGlobalRegion" : "us-east-1", - "name" : "aws", - "supportsDualStack" : true, - "supportsFIPS" : true - }, - "regionRegex" : "^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$", - "regions" : { - "af-south-1" : { - "description" : "Africa (Cape Town)" - }, - "ap-east-1" : { - "description" : "Asia Pacific (Hong Kong)" - }, - "ap-east-2" : { - "description" : "Asia Pacific (Taipei)" - }, - "ap-northeast-1" : { - "description" : "Asia Pacific (Tokyo)" - }, - "ap-northeast-2" : { - "description" : "Asia Pacific (Seoul)" - }, - "ap-northeast-3" : { - "description" : "Asia Pacific (Osaka)" - }, - "ap-south-1" : { - "description" : "Asia Pacific (Mumbai)" - }, - "ap-south-2" : { - "description" : "Asia Pacific (Hyderabad)" - }, - "ap-southeast-1" : { - "description" : "Asia Pacific (Singapore)" - }, - "ap-southeast-2" : { - "description" : "Asia Pacific (Sydney)" - }, - "ap-southeast-3" : { - "description" : "Asia Pacific (Jakarta)" - }, - "ap-southeast-4" : { - "description" : "Asia Pacific (Melbourne)" - }, - "ap-southeast-5" : { - "description" : "Asia Pacific (Malaysia)" - }, - "ap-southeast-6" : { - "description" : "Asia Pacific (New Zealand)" - }, - "ap-southeast-7" : { - "description" : "Asia Pacific (Thailand)" - }, - "aws-global" : { - "description" : "aws global region" - }, - "ca-central-1" : { - "description" : "Canada (Central)" - }, - "ca-west-1" : { - "description" : "Canada West (Calgary)" - }, - "eu-central-1" : { - "description" : "Europe (Frankfurt)" - }, - "eu-central-2" : { - "description" : "Europe (Zurich)" - }, - "eu-north-1" : { - "description" : "Europe (Stockholm)" - }, - "eu-south-1" : { - "description" : "Europe (Milan)" - }, - "eu-south-2" : { - "description" : "Europe (Spain)" - }, - "eu-west-1" : { - "description" : "Europe (Ireland)" - }, - "eu-west-2" : { - "description" : "Europe (London)" - }, - "eu-west-3" : { - "description" : "Europe (Paris)" - }, - "il-central-1" : { - "description" : "Israel (Tel Aviv)" - }, - "me-central-1" : { - "description" : "Middle East (UAE)" - }, - "me-south-1" : { - "description" : "Middle East (Bahrain)" - }, - "mx-central-1" : { - "description" : "Mexico (Central)" - }, - "sa-east-1" : { - "description" : "South America (Sao Paulo)" - }, - "us-east-1" : { - "description" : "US East (N. Virginia)" - }, - "us-east-2" : { - "description" : "US East (Ohio)" - }, - "us-west-1" : { - "description" : "US West (N. California)" - }, - "us-west-2" : { - "description" : "US West (Oregon)" - } - } - }, { - "id" : "aws-cn", - "outputs" : { - "dnsSuffix" : "amazonaws.com.cn", - "dualStackDnsSuffix" : "api.amazonwebservices.com.cn", - "implicitGlobalRegion" : "cn-northwest-1", - "name" : "aws-cn", - "supportsDualStack" : true, - "supportsFIPS" : true - }, - "regionRegex" : "^cn\\-\\w+\\-\\d+$", - "regions" : { - "aws-cn-global" : { - "description" : "aws-cn global region" - }, - "cn-north-1" : { - "description" : "China (Beijing)" - }, - "cn-northwest-1" : { - "description" : "China (Ningxia)" - } - } - }, { - "id" : "aws-eusc", - "outputs" : { - "dnsSuffix" : "amazonaws.eu", - "dualStackDnsSuffix" : "api.amazonwebservices.eu", - "implicitGlobalRegion" : "eusc-de-east-1", - "name" : "aws-eusc", - "supportsDualStack" : true, - "supportsFIPS" : true - }, - "regionRegex" : "^eusc\\-(de)\\-\\w+\\-\\d+$", - "regions" : { - "eusc-de-east-1" : { - "description" : "EU (Germany)" - } - } - }, { - "id" : "aws-iso", - "outputs" : { - "dnsSuffix" : "c2s.ic.gov", - "dualStackDnsSuffix" : "api.aws.ic.gov", - "implicitGlobalRegion" : "us-iso-east-1", - "name" : "aws-iso", - "supportsDualStack" : true, - "supportsFIPS" : true - }, - "regionRegex" : "^us\\-iso\\-\\w+\\-\\d+$", - "regions" : { - "aws-iso-global" : { - "description" : "aws-iso global region" - }, - "us-iso-east-1" : { - "description" : "US ISO East" - }, - "us-iso-west-1" : { - "description" : "US ISO WEST" - } - } - }, { - "id" : "aws-iso-b", - "outputs" : { - "dnsSuffix" : "sc2s.sgov.gov", - "dualStackDnsSuffix" : "api.aws.scloud", - "implicitGlobalRegion" : "us-isob-east-1", - "name" : "aws-iso-b", - "supportsDualStack" : true, - "supportsFIPS" : true - }, - "regionRegex" : "^us\\-isob\\-\\w+\\-\\d+$", - "regions" : { - "aws-iso-b-global" : { - "description" : "aws-iso-b global region" - }, - "us-isob-east-1" : { - "description" : "US ISOB East (Ohio)" - }, - "us-isob-west-1" : { - "description" : "US ISOB West" - } - } - }, { - "id" : "aws-iso-e", - "outputs" : { - "dnsSuffix" : "cloud.adc-e.uk", - "dualStackDnsSuffix" : "api.cloud-aws.adc-e.uk", - "implicitGlobalRegion" : "eu-isoe-west-1", - "name" : "aws-iso-e", - "supportsDualStack" : true, - "supportsFIPS" : true - }, - "regionRegex" : "^eu\\-isoe\\-\\w+\\-\\d+$", - "regions" : { - "aws-iso-e-global" : { - "description" : "aws-iso-e global region" - }, - "eu-isoe-west-1" : { - "description" : "EU ISOE West" - } - } - }, { - "id" : "aws-iso-f", - "outputs" : { - "dnsSuffix" : "csp.hci.ic.gov", - "dualStackDnsSuffix" : "api.aws.hci.ic.gov", - "implicitGlobalRegion" : "us-isof-south-1", - "name" : "aws-iso-f", - "supportsDualStack" : true, - "supportsFIPS" : true - }, - "regionRegex" : "^us\\-isof\\-\\w+\\-\\d+$", - "regions" : { - "aws-iso-f-global" : { - "description" : "aws-iso-f global region" - }, - "us-isof-east-1" : { - "description" : "US ISOF EAST" - }, - "us-isof-south-1" : { - "description" : "US ISOF SOUTH" - } - } - }, { - "id" : "aws-us-gov", - "outputs" : { - "dnsSuffix" : "amazonaws.com", - "dualStackDnsSuffix" : "api.aws", - "implicitGlobalRegion" : "us-gov-west-1", - "name" : "aws-us-gov", - "supportsDualStack" : true, - "supportsFIPS" : true - }, - "regionRegex" : "^us\\-gov\\-\\w+\\-\\d+$", - "regions" : { - "aws-us-gov-global" : { - "description" : "aws-us-gov global region" - }, - "us-gov-east-1" : { - "description" : "AWS GovCloud (US-East)" - }, - "us-gov-west-1" : { - "description" : "AWS GovCloud (US-West)" - } - } - } ], - "version" : "1.1" -} \ No newline at end of file diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/endpoints.go deleted file mode 100644 index 67950ca..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/endpoints.go +++ /dev/null @@ -1,201 +0,0 @@ -package endpoints - -import ( - "fmt" - "regexp" - "strings" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -const ( - defaultProtocol = "https" - defaultSigner = "v4" -) - -var ( - protocolPriority = []string{"https", "http"} - signerPriority = []string{"v4"} -) - -// Options provide configuration needed to direct how endpoints are resolved. -type Options struct { - // Disable usage of HTTPS (TLS / SSL) - DisableHTTPS bool -} - -// Partitions is a slice of partition -type Partitions []Partition - -// ResolveEndpoint resolves a service endpoint for the given region and options. -func (ps Partitions) ResolveEndpoint(region string, opts Options) (aws.Endpoint, error) { - if len(ps) == 0 { - return aws.Endpoint{}, fmt.Errorf("no partitions found") - } - - for i := 0; i < len(ps); i++ { - if !ps[i].canResolveEndpoint(region) { - continue - } - - return ps[i].ResolveEndpoint(region, opts) - } - - // fallback to first partition format to use when resolving the endpoint. - return ps[0].ResolveEndpoint(region, opts) -} - -// Partition is an AWS partition description for a service and its' region endpoints. -type Partition struct { - ID string - RegionRegex *regexp.Regexp - PartitionEndpoint string - IsRegionalized bool - Defaults Endpoint - Endpoints Endpoints -} - -func (p Partition) canResolveEndpoint(region string) bool { - _, ok := p.Endpoints[region] - return ok || p.RegionRegex.MatchString(region) -} - -// ResolveEndpoint resolves and service endpoint for the given region and options. -func (p Partition) ResolveEndpoint(region string, options Options) (resolved aws.Endpoint, err error) { - if len(region) == 0 && len(p.PartitionEndpoint) != 0 { - region = p.PartitionEndpoint - } - - e, _ := p.endpointForRegion(region) - - return e.resolve(p.ID, region, p.Defaults, options), nil -} - -func (p Partition) endpointForRegion(region string) (Endpoint, bool) { - if e, ok := p.Endpoints[region]; ok { - return e, true - } - - if !p.IsRegionalized { - return p.Endpoints[p.PartitionEndpoint], region == p.PartitionEndpoint - } - - // Unable to find any matching endpoint, return - // blank that will be used for generic endpoint creation. - return Endpoint{}, false -} - -// Endpoints is a map of service config regions to endpoints -type Endpoints map[string]Endpoint - -// CredentialScope is the credential scope of a region and service -type CredentialScope struct { - Region string - Service string -} - -// Endpoint is a service endpoint description -type Endpoint struct { - // True if the endpoint cannot be resolved for this partition/region/service - Unresolveable aws.Ternary - - Hostname string - Protocols []string - - CredentialScope CredentialScope - - SignatureVersions []string `json:"signatureVersions"` -} - -func (e Endpoint) resolve(partition, region string, def Endpoint, options Options) aws.Endpoint { - var merged Endpoint - merged.mergeIn(def) - merged.mergeIn(e) - e = merged - - var u string - if e.Unresolveable != aws.TrueTernary { - // Only attempt to resolve the endpoint if it can be resolved. - hostname := strings.Replace(e.Hostname, "{region}", region, 1) - - scheme := getEndpointScheme(e.Protocols, options.DisableHTTPS) - u = scheme + "://" + hostname - } - - signingRegion := e.CredentialScope.Region - if len(signingRegion) == 0 { - signingRegion = region - } - signingName := e.CredentialScope.Service - - return aws.Endpoint{ - URL: u, - PartitionID: partition, - SigningRegion: signingRegion, - SigningName: signingName, - SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner), - } -} - -func (e *Endpoint) mergeIn(other Endpoint) { - if other.Unresolveable != aws.UnknownTernary { - e.Unresolveable = other.Unresolveable - } - if len(other.Hostname) > 0 { - e.Hostname = other.Hostname - } - if len(other.Protocols) > 0 { - e.Protocols = other.Protocols - } - if len(other.CredentialScope.Region) > 0 { - e.CredentialScope.Region = other.CredentialScope.Region - } - if len(other.CredentialScope.Service) > 0 { - e.CredentialScope.Service = other.CredentialScope.Service - } - if len(other.SignatureVersions) > 0 { - e.SignatureVersions = other.SignatureVersions - } -} - -func getEndpointScheme(protocols []string, disableHTTPS bool) string { - if disableHTTPS { - return "http" - } - - return getByPriority(protocols, protocolPriority, defaultProtocol) -} - -func getByPriority(s []string, p []string, def string) string { - if len(s) == 0 { - return def - } - - for i := 0; i < len(p); i++ { - for j := 0; j < len(s); j++ { - if s[j] == p[i] { - return s[j] - } - } - } - - return s[0] -} - -// MapFIPSRegion extracts the intrinsic AWS region from one that may have an -// embedded FIPS microformat. -func MapFIPSRegion(region string) string { - const fipsInfix = "-fips-" - const fipsPrefix = "fips-" - const fipsSuffix = "-fips" - - if strings.Contains(region, fipsInfix) || - strings.Contains(region, fipsPrefix) || - strings.Contains(region, fipsSuffix) { - region = strings.ReplaceAll(region, fipsInfix, "-") - region = strings.ReplaceAll(region, fipsPrefix, "") - region = strings.ReplaceAll(region, fipsSuffix, "") - } - - return region -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md deleted file mode 100644 index b2d3477..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md +++ /dev/null @@ -1,461 +0,0 @@ -# v2.7.16 (2025-12-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.15 (2025-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. - -# v2.7.14 (2025-11-19.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.13 (2025-11-04) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. - -# v2.7.12 (2025-10-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.11 (2025-10-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.10 (2025-10-16) - -* **Dependency Update**: Bump minimum Go version to 1.23. -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.9 (2025-09-26) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.8 (2025-09-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.7 (2025-09-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.6 (2025-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.5 (2025-08-27) - -* **Dependency Update**: Update to smithy-go v1.23.0. -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.4 (2025-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.3 (2025-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.2 (2025-08-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.1 (2025-07-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.7.0 (2025-07-28) - -* **Feature**: Add support for HTTP interceptors. -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.37 (2025-07-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.36 (2025-06-17) - -* **Dependency Update**: Update to smithy-go v1.22.4. -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.35 (2025-06-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.34 (2025-02-27) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.33 (2025-02-18) - -* **Bug Fix**: Bump go version to 1.22 -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.32 (2025-02-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.31 (2025-01-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.30 (2025-01-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.29 (2025-01-24) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v2.6.28 (2025-01-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.27 (2025-01-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.26 (2024-12-19) - -* **Bug Fix**: Fix improper use of printf-style functions. -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.25 (2024-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.24 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.23 (2024-11-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.22 (2024-10-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.21 (2024-10-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.20 (2024-10-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.19 (2024-10-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.18 (2024-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.17 (2024-09-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.16 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.15 (2024-07-10.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.14 (2024-07-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.13 (2024-06-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.12 (2024-06-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.11 (2024-06-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.10 (2024-06-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.9 (2024-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.8 (2024-06-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.7 (2024-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.6 (2024-05-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.5 (2024-03-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.4 (2024-03-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.3 (2024-03-07) - -* **Bug Fix**: Remove dependency on go-cmp. -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.2 (2024-02-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.1 (2024-02-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.6.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.10 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.9 (2023-12-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.8 (2023-12-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.7 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.6 (2023-11-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.5 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.4 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.3 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.2 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.1 (2023-11-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.5.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.37 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.36 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.35 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.34 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.33 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.32 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.31 (2023-07-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.30 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.29 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.28 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.27 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.26 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.25 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.24 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.23 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.22 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.21 (2022-12-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.20 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.19 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.18 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.17 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.16 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.15 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.14 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.13 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.12 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.11 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.10 (2022-08-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.9 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.8 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.7 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.6 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.5 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.4 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.3 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.2 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.1 (2022-03-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.4.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.3.0 (2022-02-24) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.2.0 (2022-01-14) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.1.0 (2022-01-07) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.0.2 (2021-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.0.1 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v2.0.0 (2021-11-06) - -* **Release**: Endpoint Variant Model Support -* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/endpoints.go deleted file mode 100644 index 32251a7..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/endpoints.go +++ /dev/null @@ -1,302 +0,0 @@ -package endpoints - -import ( - "fmt" - "github.com/aws/smithy-go/logging" - "regexp" - "strings" - - "github.com/aws/aws-sdk-go-v2/aws" -) - -// DefaultKey is a compound map key of a variant and other values. -type DefaultKey struct { - Variant EndpointVariant - ServiceVariant ServiceVariant -} - -// EndpointKey is a compound map key of a region and associated variant value. -type EndpointKey struct { - Region string - Variant EndpointVariant - ServiceVariant ServiceVariant -} - -// EndpointVariant is a bit field to describe the endpoints attributes. -type EndpointVariant uint64 - -const ( - // FIPSVariant indicates that the endpoint is FIPS capable. - FIPSVariant EndpointVariant = 1 << (64 - 1 - iota) - - // DualStackVariant indicates that the endpoint is DualStack capable. - DualStackVariant -) - -// ServiceVariant is a bit field to describe the service endpoint attributes. -type ServiceVariant uint64 - -const ( - defaultProtocol = "https" - defaultSigner = "v4" -) - -var ( - protocolPriority = []string{"https", "http"} - signerPriority = []string{"v4", "s3v4"} -) - -// Options provide configuration needed to direct how endpoints are resolved. -type Options struct { - // Logger is a logging implementation that log events should be sent to. - Logger logging.Logger - - // LogDeprecated indicates that deprecated endpoints should be logged to the provided logger. - LogDeprecated bool - - // ResolvedRegion is the resolved region string. If provided (non-zero length) it takes priority - // over the region name passed to the ResolveEndpoint call. - ResolvedRegion string - - // Disable usage of HTTPS (TLS / SSL) - DisableHTTPS bool - - // Instruct the resolver to use a service endpoint that supports dual-stack. - // If a service does not have a dual-stack endpoint an error will be returned by the resolver. - UseDualStackEndpoint aws.DualStackEndpointState - - // Instruct the resolver to use a service endpoint that supports FIPS. - // If a service does not have a FIPS endpoint an error will be returned by the resolver. - UseFIPSEndpoint aws.FIPSEndpointState - - // ServiceVariant is a bitfield of service specified endpoint variant data. - ServiceVariant ServiceVariant -} - -// GetEndpointVariant returns the EndpointVariant for the variant associated options. -func (o Options) GetEndpointVariant() (v EndpointVariant) { - if o.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled { - v |= DualStackVariant - } - if o.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled { - v |= FIPSVariant - } - return v -} - -// Partitions is a slice of partition -type Partitions []Partition - -// ResolveEndpoint resolves a service endpoint for the given region and options. -func (ps Partitions) ResolveEndpoint(region string, opts Options) (aws.Endpoint, error) { - if len(ps) == 0 { - return aws.Endpoint{}, fmt.Errorf("no partitions found") - } - - if opts.Logger == nil { - opts.Logger = logging.Nop{} - } - - if len(opts.ResolvedRegion) > 0 { - region = opts.ResolvedRegion - } - - for i := 0; i < len(ps); i++ { - if !ps[i].canResolveEndpoint(region, opts) { - continue - } - - return ps[i].ResolveEndpoint(region, opts) - } - - // fallback to first partition format to use when resolving the endpoint. - return ps[0].ResolveEndpoint(region, opts) -} - -// Partition is an AWS partition description for a service and its' region endpoints. -type Partition struct { - ID string - RegionRegex *regexp.Regexp - PartitionEndpoint string - IsRegionalized bool - Defaults map[DefaultKey]Endpoint - Endpoints Endpoints -} - -func (p Partition) canResolveEndpoint(region string, opts Options) bool { - _, ok := p.Endpoints[EndpointKey{ - Region: region, - Variant: opts.GetEndpointVariant(), - }] - return ok || p.RegionRegex.MatchString(region) -} - -// ResolveEndpoint resolves and service endpoint for the given region and options. -func (p Partition) ResolveEndpoint(region string, options Options) (resolved aws.Endpoint, err error) { - if len(region) == 0 && len(p.PartitionEndpoint) != 0 { - region = p.PartitionEndpoint - } - - endpoints := p.Endpoints - - variant := options.GetEndpointVariant() - serviceVariant := options.ServiceVariant - - defaults := p.Defaults[DefaultKey{ - Variant: variant, - ServiceVariant: serviceVariant, - }] - - return p.endpointForRegion(region, variant, serviceVariant, endpoints).resolve(p.ID, region, defaults, options) -} - -func (p Partition) endpointForRegion(region string, variant EndpointVariant, serviceVariant ServiceVariant, endpoints Endpoints) Endpoint { - key := EndpointKey{ - Region: region, - Variant: variant, - } - - if e, ok := endpoints[key]; ok { - return e - } - - if !p.IsRegionalized { - return endpoints[EndpointKey{ - Region: p.PartitionEndpoint, - Variant: variant, - ServiceVariant: serviceVariant, - }] - } - - // Unable to find any matching endpoint, return - // blank that will be used for generic endpoint creation. - return Endpoint{} -} - -// Endpoints is a map of service config regions to endpoints -type Endpoints map[EndpointKey]Endpoint - -// CredentialScope is the credential scope of a region and service -type CredentialScope struct { - Region string - Service string -} - -// Endpoint is a service endpoint description -type Endpoint struct { - // True if the endpoint cannot be resolved for this partition/region/service - Unresolveable aws.Ternary - - Hostname string - Protocols []string - - CredentialScope CredentialScope - - SignatureVersions []string - - // Indicates that this endpoint is deprecated. - Deprecated aws.Ternary -} - -// IsZero returns whether the endpoint structure is an empty (zero) value. -func (e Endpoint) IsZero() bool { - switch { - case e.Unresolveable != aws.UnknownTernary: - return false - case len(e.Hostname) != 0: - return false - case len(e.Protocols) != 0: - return false - case e.CredentialScope != (CredentialScope{}): - return false - case len(e.SignatureVersions) != 0: - return false - } - return true -} - -func (e Endpoint) resolve(partition, region string, def Endpoint, options Options) (aws.Endpoint, error) { - var merged Endpoint - merged.mergeIn(def) - merged.mergeIn(e) - e = merged - - if e.IsZero() { - return aws.Endpoint{}, fmt.Errorf("unable to resolve endpoint for region: %v", region) - } - - var u string - if e.Unresolveable != aws.TrueTernary { - // Only attempt to resolve the endpoint if it can be resolved. - hostname := strings.Replace(e.Hostname, "{region}", region, 1) - - scheme := getEndpointScheme(e.Protocols, options.DisableHTTPS) - u = scheme + "://" + hostname - } - - signingRegion := e.CredentialScope.Region - if len(signingRegion) == 0 { - signingRegion = region - } - signingName := e.CredentialScope.Service - - if e.Deprecated == aws.TrueTernary && options.LogDeprecated { - options.Logger.Logf(logging.Warn, "endpoint identifier %q, url %q marked as deprecated", region, u) - } - - return aws.Endpoint{ - URL: u, - PartitionID: partition, - SigningRegion: signingRegion, - SigningName: signingName, - SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner), - }, nil -} - -func (e *Endpoint) mergeIn(other Endpoint) { - if other.Unresolveable != aws.UnknownTernary { - e.Unresolveable = other.Unresolveable - } - if len(other.Hostname) > 0 { - e.Hostname = other.Hostname - } - if len(other.Protocols) > 0 { - e.Protocols = other.Protocols - } - if len(other.CredentialScope.Region) > 0 { - e.CredentialScope.Region = other.CredentialScope.Region - } - if len(other.CredentialScope.Service) > 0 { - e.CredentialScope.Service = other.CredentialScope.Service - } - if len(other.SignatureVersions) > 0 { - e.SignatureVersions = other.SignatureVersions - } - if other.Deprecated != aws.UnknownTernary { - e.Deprecated = other.Deprecated - } -} - -func getEndpointScheme(protocols []string, disableHTTPS bool) string { - if disableHTTPS { - return "http" - } - - return getByPriority(protocols, protocolPriority, defaultProtocol) -} - -func getByPriority(s []string, p []string, def string) string { - if len(s) == 0 { - return def - } - - for i := 0; i < len(p); i++ { - for j := 0; j < len(s); j++ { - if s[j] == p[i] { - return s[j] - } - } - } - - return s[0] -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go deleted file mode 100644 index 1a524ae..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package endpoints - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "2.7.16" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/CHANGELOG.md deleted file mode 100644 index 1d23b9b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/CHANGELOG.md +++ /dev/null @@ -1,279 +0,0 @@ -# v1.8.2 (2025-01-24) - -* **Bug Fix**: Refactor filepath.Walk to filepath.WalkDir - -# v1.8.1 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. - -# v1.8.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. - -# v1.7.3 (2024-01-22) - -* **Bug Fix**: Remove invalid escaping of shared config values. All values in the shared config file will now be interpreted literally, save for fully-quoted strings which are unwrapped for legacy reasons. - -# v1.7.2 (2023-12-08) - -* **Bug Fix**: Correct loading of [services *] sections into shared config. - -# v1.7.1 (2023-11-16) - -* **Bug Fix**: Fix recognition of trailing comments in shared config properties. # or ; separators that aren't preceded by whitespace at the end of a property value should be considered part of it. - -# v1.7.0 (2023-11-13) - -* **Feature**: Replace the legacy config parser with a modern, less-strict implementation. Parsing failures within a section will now simply ignore the invalid line rather than silently drop the entire section. - -# v1.6.0 (2023-11-09.2) - -* **Feature**: BREAKFIX: In order to support subproperty parsing, invalid property definitions must not be ignored - -# v1.5.2 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.1 (2023-11-07) - -* **Bug Fix**: Fix subproperty performance regression - -# v1.5.0 (2023-11-01) - -* **Feature**: Adds support for configured endpoints via environment variables and the AWS shared configuration file. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.45 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.44 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.43 (2023-09-22) - -* **Bug Fix**: Fixed a bug where merging `max_attempts` or `duration_seconds` fields across shared config files with invalid values would silently default them to 0. -* **Bug Fix**: Move type assertion of config values out of the parsing stage, which resolves an issue where the contents of a profile would silently be dropped with certain numeric formats. - -# v1.3.42 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.41 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.40 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.39 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.38 (2023-07-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.37 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.36 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.35 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.34 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.33 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.32 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.31 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.30 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.29 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.28 (2022-12-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.27 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.26 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.25 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.24 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.23 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.22 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.21 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.20 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.19 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.18 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.17 (2022-08-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.16 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.15 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.14 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.13 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.12 (2022-05-17) - -* **Bug Fix**: Removes the fuzz testing files from the module, as they are invalid and not used. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.11 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.10 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.9 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.8 (2022-03-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.7 (2022-03-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.6 (2022-02-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.5 (2022-01-28) - -* **Bug Fix**: Fixes the SDK's handling of `duration_sections` in the shared credentials file or specified in multiple shared config and shared credentials files under the same profile. [#1568](https://github.com/aws/aws-sdk-go-v2/pull/1568). Thanks to [Amir Szekely](https://github.com/kichik) for help reproduce this bug. - -# v1.3.4 (2022-01-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.3 (2022-01-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.2 (2021-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.1 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.0 (2021-11-06) - -* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.5 (2021-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.4 (2021-10-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.3 (2021-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.2 (2021-08-27) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.1 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.0 (2021-08-04) - -* **Feature**: adds error handling for defered close calls -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.1 (2021-07-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.0 (2021-07-01) - -* **Feature**: Support for `:`, `=`, `[`, `]` being present in expression values. - -# v1.0.1 (2021-06-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.0.0 (2021-05-20) - -* **Release**: The `github.com/aws/aws-sdk-go-v2/internal/ini` package is now a Go Module. -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/errors.go deleted file mode 100644 index 0f278d5..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/errors.go +++ /dev/null @@ -1,22 +0,0 @@ -package ini - -import "fmt" - -// UnableToReadFile is an error indicating that a ini file could not be read -type UnableToReadFile struct { - Err error -} - -// Error returns an error message and the underlying error message if present -func (e *UnableToReadFile) Error() string { - base := "unable to read file" - if e.Err == nil { - return base - } - return fmt.Sprintf("%s: %v", base, e.Err) -} - -// Unwrap returns the underlying error -func (e *UnableToReadFile) Unwrap() error { - return e.Err -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/go_module_metadata.go deleted file mode 100644 index 355ed39..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package ini - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.8.2" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/ini.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/ini.go deleted file mode 100644 index cefcce9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/ini.go +++ /dev/null @@ -1,56 +0,0 @@ -// Package ini implements parsing of the AWS shared config file. -// -// Example: -// sections, err := ini.OpenFile("/path/to/file") -// if err != nil { -// panic(err) -// } -// -// profile := "foo" -// section, ok := sections.GetSection(profile) -// if !ok { -// fmt.Printf("section %q could not be found", profile) -// } -package ini - -import ( - "fmt" - "io" - "os" - "strings" -) - -// OpenFile parses shared config from the given file path. -func OpenFile(path string) (sections Sections, err error) { - f, oerr := os.Open(path) - if oerr != nil { - return Sections{}, &UnableToReadFile{Err: oerr} - } - - defer func() { - closeErr := f.Close() - if err == nil { - err = closeErr - } else if closeErr != nil { - err = fmt.Errorf("close error: %v, original error: %w", closeErr, err) - } - }() - - return Parse(f, path) -} - -// Parse parses shared config from the given reader. -func Parse(r io.Reader, path string) (Sections, error) { - contents, err := io.ReadAll(r) - if err != nil { - return Sections{}, fmt.Errorf("read all: %v", err) - } - - lines := strings.Split(string(contents), "\n") - tokens, err := tokenize(lines) - if err != nil { - return Sections{}, fmt.Errorf("tokenize: %v", err) - } - - return parse(tokens, path), nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/parse.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/parse.go deleted file mode 100644 index 2422d90..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/parse.go +++ /dev/null @@ -1,109 +0,0 @@ -package ini - -import ( - "fmt" - "strings" -) - -func parse(tokens []lineToken, path string) Sections { - parser := &parser{ - path: path, - sections: NewSections(), - } - parser.parse(tokens) - return parser.sections -} - -type parser struct { - csection, ckey string // current state - path string // source file path - sections Sections // parse result -} - -func (p *parser) parse(tokens []lineToken) { - for _, otok := range tokens { - switch tok := otok.(type) { - case *lineTokenProfile: - p.handleProfile(tok) - case *lineTokenProperty: - p.handleProperty(tok) - case *lineTokenSubProperty: - p.handleSubProperty(tok) - case *lineTokenContinuation: - p.handleContinuation(tok) - } - } -} - -func (p *parser) handleProfile(tok *lineTokenProfile) { - name := tok.Name - if tok.Type != "" { - name = fmt.Sprintf("%s %s", tok.Type, tok.Name) - } - p.ckey = "" - p.csection = name - if _, ok := p.sections.container[name]; !ok { - p.sections.container[name] = NewSection(name) - } -} - -func (p *parser) handleProperty(tok *lineTokenProperty) { - if p.csection == "" { - return // LEGACY: don't error on "global" properties - } - - p.ckey = tok.Key - if _, ok := p.sections.container[p.csection].values[tok.Key]; ok { - section := p.sections.container[p.csection] - section.Logs = append(p.sections.container[p.csection].Logs, - fmt.Sprintf( - "For profile: %v, overriding %v value, with a %v value found in a duplicate profile defined later in the same file %v. \n", - p.csection, tok.Key, tok.Key, p.path, - ), - ) - p.sections.container[p.csection] = section - } - - p.sections.container[p.csection].values[tok.Key] = Value{ - str: tok.Value, - } - p.sections.container[p.csection].SourceFile[tok.Key] = p.path -} - -func (p *parser) handleSubProperty(tok *lineTokenSubProperty) { - if p.csection == "" { - return // LEGACY: don't error on "global" properties - } - - if p.ckey == "" || p.sections.container[p.csection].values[p.ckey].str != "" { - // This is an "orphaned" subproperty, either because it's at - // the beginning of a section or because the last property's - // value isn't empty. Either way we're lenient here and - // "promote" this to a normal property. - p.handleProperty(&lineTokenProperty{ - Key: tok.Key, - Value: strings.TrimSpace(trimPropertyComment(tok.Value)), - }) - return - } - - if p.sections.container[p.csection].values[p.ckey].mp == nil { - p.sections.container[p.csection].values[p.ckey] = Value{ - mp: map[string]string{}, - } - } - p.sections.container[p.csection].values[p.ckey].mp[tok.Key] = tok.Value -} - -func (p *parser) handleContinuation(tok *lineTokenContinuation) { - if p.ckey == "" { - return - } - - value, _ := p.sections.container[p.csection].values[p.ckey] - if value.str != "" && value.mp == nil { - value.str = fmt.Sprintf("%s\n%s", value.str, tok.Value) - } - - p.sections.container[p.csection].values[p.ckey] = value -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/sections.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/sections.go deleted file mode 100644 index dd89848..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/sections.go +++ /dev/null @@ -1,157 +0,0 @@ -package ini - -import ( - "sort" -) - -// Sections is a map of Section structures that represent -// a configuration. -type Sections struct { - container map[string]Section -} - -// NewSections returns empty ini Sections -func NewSections() Sections { - return Sections{ - container: make(map[string]Section, 0), - } -} - -// GetSection will return section p. If section p does not exist, -// false will be returned in the second parameter. -func (t Sections) GetSection(p string) (Section, bool) { - v, ok := t.container[p] - return v, ok -} - -// HasSection denotes if Sections consist of a section with -// provided name. -func (t Sections) HasSection(p string) bool { - _, ok := t.container[p] - return ok -} - -// SetSection sets a section value for provided section name. -func (t Sections) SetSection(p string, v Section) Sections { - t.container[p] = v - return t -} - -// DeleteSection deletes a section entry/value for provided section name./ -func (t Sections) DeleteSection(p string) { - delete(t.container, p) -} - -// values represents a map of union values. -type values map[string]Value - -// List will return a list of all sections that were successfully -// parsed. -func (t Sections) List() []string { - keys := make([]string, len(t.container)) - i := 0 - for k := range t.container { - keys[i] = k - i++ - } - - sort.Strings(keys) - return keys -} - -// Section contains a name and values. This represent -// a sectioned entry in a configuration file. -type Section struct { - // Name is the Section profile name - Name string - - // values are the values within parsed profile - values values - - // Errors is the list of errors - Errors []error - - // Logs is the list of logs - Logs []string - - // SourceFile is the INI Source file from where this section - // was retrieved. They key is the property, value is the - // source file the property was retrieved from. - SourceFile map[string]string -} - -// NewSection returns an initialize section for the name -func NewSection(name string) Section { - return Section{ - Name: name, - values: values{}, - SourceFile: map[string]string{}, - } -} - -// List will return a list of all -// services in values -func (t Section) List() []string { - keys := make([]string, len(t.values)) - i := 0 - for k := range t.values { - keys[i] = k - i++ - } - - sort.Strings(keys) - return keys -} - -// UpdateSourceFile updates source file for a property to provided filepath. -func (t Section) UpdateSourceFile(property string, filepath string) { - t.SourceFile[property] = filepath -} - -// UpdateValue updates value for a provided key with provided value -func (t Section) UpdateValue(k string, v Value) error { - t.values[k] = v - return nil -} - -// Has will return whether or not an entry exists in a given section -func (t Section) Has(k string) bool { - _, ok := t.values[k] - return ok -} - -// ValueType will returned what type the union is set to. If -// k was not found, the NoneType will be returned. -func (t Section) ValueType(k string) (ValueType, bool) { - v, ok := t.values[k] - return v.Type, ok -} - -// Bool returns a bool value at k -func (t Section) Bool(k string) (bool, bool) { - return t.values[k].BoolValue() -} - -// Int returns an integer value at k -func (t Section) Int(k string) (int64, bool) { - return t.values[k].IntValue() -} - -// Map returns a map value at k -func (t Section) Map(k string) map[string]string { - return t.values[k].MapValue() -} - -// Float64 returns a float value at k -func (t Section) Float64(k string) (float64, bool) { - return t.values[k].FloatValue() -} - -// String returns the string value at k -func (t Section) String(k string) string { - _, ok := t.values[k] - if !ok { - return "" - } - return t.values[k].StringValue() -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/strings.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/strings.go deleted file mode 100644 index ed77d08..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/strings.go +++ /dev/null @@ -1,89 +0,0 @@ -package ini - -import ( - "strings" -) - -func trimProfileComment(s string) string { - r, _, _ := strings.Cut(s, "#") - r, _, _ = strings.Cut(r, ";") - return r -} - -func trimPropertyComment(s string) string { - r, _, _ := strings.Cut(s, " #") - r, _, _ = strings.Cut(r, " ;") - r, _, _ = strings.Cut(r, "\t#") - r, _, _ = strings.Cut(r, "\t;") - return r -} - -// assumes no surrounding comment -func splitProperty(s string) (string, string, bool) { - equalsi := strings.Index(s, "=") - coloni := strings.Index(s, ":") // LEGACY: also supported for property assignment - sep := "=" - if equalsi == -1 || coloni != -1 && coloni < equalsi { - sep = ":" - } - - k, v, ok := strings.Cut(s, sep) - if !ok { - return "", "", false - } - return strings.TrimSpace(k), strings.TrimSpace(v), true -} - -// assumes no surrounding comment, whitespace, or profile brackets -func splitProfile(s string) (string, string) { - var first int - for i, r := range s { - if isLineSpace(r) { - if first == 0 { - first = i - } - } else { - if first != 0 { - return s[:first], s[i:] - } - } - } - if first == 0 { - return "", s // type component is effectively blank - } - return "", "" -} - -func isLineSpace(r rune) bool { - return r == ' ' || r == '\t' -} - -func unquote(s string) string { - if isSingleQuoted(s) || isDoubleQuoted(s) { - return s[1 : len(s)-1] - } - return s -} - -// applies various legacy conversions to property values: -// - remote wrapping single/doublequotes -func legacyStrconv(s string) string { - s = unquote(s) - return s -} - -func isSingleQuoted(s string) bool { - return hasAffixes(s, "'", "'") -} - -func isDoubleQuoted(s string) bool { - return hasAffixes(s, `"`, `"`) -} - -func isBracketed(s string) bool { - return hasAffixes(s, "[", "]") -} - -func hasAffixes(s, left, right string) bool { - return strings.HasPrefix(s, left) && strings.HasSuffix(s, right) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/token.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/token.go deleted file mode 100644 index 6e9a037..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/token.go +++ /dev/null @@ -1,32 +0,0 @@ -package ini - -type lineToken interface { - isLineToken() -} - -type lineTokenProfile struct { - Type string - Name string -} - -func (*lineTokenProfile) isLineToken() {} - -type lineTokenProperty struct { - Key string - Value string -} - -func (*lineTokenProperty) isLineToken() {} - -type lineTokenContinuation struct { - Value string -} - -func (*lineTokenContinuation) isLineToken() {} - -type lineTokenSubProperty struct { - Key string - Value string -} - -func (*lineTokenSubProperty) isLineToken() {} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/tokenize.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/tokenize.go deleted file mode 100644 index 89a7736..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/tokenize.go +++ /dev/null @@ -1,92 +0,0 @@ -package ini - -import ( - "strings" -) - -func tokenize(lines []string) ([]lineToken, error) { - tokens := make([]lineToken, 0, len(lines)) - for _, line := range lines { - if len(strings.TrimSpace(line)) == 0 || isLineComment(line) { - continue - } - - if tok := asProfile(line); tok != nil { - tokens = append(tokens, tok) - } else if tok := asProperty(line); tok != nil { - tokens = append(tokens, tok) - } else if tok := asSubProperty(line); tok != nil { - tokens = append(tokens, tok) - } else if tok := asContinuation(line); tok != nil { - tokens = append(tokens, tok) - } // unrecognized tokens are effectively ignored - } - return tokens, nil -} - -func isLineComment(line string) bool { - trimmed := strings.TrimLeft(line, " \t") - return strings.HasPrefix(trimmed, "#") || strings.HasPrefix(trimmed, ";") -} - -func asProfile(line string) *lineTokenProfile { // " [ type name ] ; comment" - trimmed := strings.TrimSpace(trimProfileComment(line)) // "[ type name ]" - if !isBracketed(trimmed) { - return nil - } - trimmed = trimmed[1 : len(trimmed)-1] // " type name " (or just " name ") - trimmed = strings.TrimSpace(trimmed) // "type name" / "name" - typ, name := splitProfile(trimmed) - return &lineTokenProfile{ - Type: typ, - Name: name, - } -} - -func asProperty(line string) *lineTokenProperty { - if isLineSpace(rune(line[0])) { - return nil - } - - trimmed := trimPropertyComment(line) - trimmed = strings.TrimRight(trimmed, " \t") - k, v, ok := splitProperty(trimmed) - if !ok { - return nil - } - - return &lineTokenProperty{ - Key: strings.ToLower(k), // LEGACY: normalize key case - Value: legacyStrconv(v), // LEGACY: see func docs - } -} - -func asSubProperty(line string) *lineTokenSubProperty { - if !isLineSpace(rune(line[0])) { - return nil - } - - // comments on sub-properties are included in the value - trimmed := strings.TrimLeft(line, " \t") - k, v, ok := splitProperty(trimmed) - if !ok { - return nil - } - - return &lineTokenSubProperty{ // same LEGACY constraints as in normal property - Key: strings.ToLower(k), - Value: legacyStrconv(v), - } -} - -func asContinuation(line string) *lineTokenContinuation { - if !isLineSpace(rune(line[0])) { - return nil - } - - // includes comments like sub-properties - trimmed := strings.TrimLeft(line, " \t") - return &lineTokenContinuation{ - Value: trimmed, - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/value.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/value.go deleted file mode 100644 index e3706b3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/value.go +++ /dev/null @@ -1,93 +0,0 @@ -package ini - -import ( - "fmt" - "strconv" - "strings" -) - -// ValueType is an enum that will signify what type -// the Value is -type ValueType int - -func (v ValueType) String() string { - switch v { - case NoneType: - return "NONE" - case StringType: - return "STRING" - } - - return "" -} - -// ValueType enums -const ( - NoneType = ValueType(iota) - StringType - QuotedStringType -) - -// Value is a union container -type Value struct { - Type ValueType - - str string - mp map[string]string -} - -// NewStringValue returns a Value type generated using a string input. -func NewStringValue(str string) (Value, error) { - return Value{str: str}, nil -} - -func (v Value) String() string { - switch v.Type { - case StringType: - return fmt.Sprintf("string: %s", string(v.str)) - case QuotedStringType: - return fmt.Sprintf("quoted string: %s", string(v.str)) - default: - return "union not set" - } -} - -// MapValue returns a map value for sub properties -func (v Value) MapValue() map[string]string { - return v.mp -} - -// IntValue returns an integer value -func (v Value) IntValue() (int64, bool) { - i, err := strconv.ParseInt(string(v.str), 0, 64) - if err != nil { - return 0, false - } - return i, true -} - -// FloatValue returns a float value -func (v Value) FloatValue() (float64, bool) { - f, err := strconv.ParseFloat(string(v.str), 64) - if err != nil { - return 0, false - } - return f, true -} - -// BoolValue returns a bool value -func (v Value) BoolValue() (bool, bool) { - // we don't use ParseBool as it recognizes more than what we've - // historically supported - if strings.EqualFold(v.str, "true") { - return true, true - } else if strings.EqualFold(v.str, "false") { - return false, true - } - return false, false -} - -// StringValue returns the string value -func (v Value) StringValue() string { - return v.str -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/middleware/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/middleware/middleware.go deleted file mode 100644 index 8e24a3f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/middleware/middleware.go +++ /dev/null @@ -1,42 +0,0 @@ -package middleware - -import ( - "context" - "sync/atomic" - "time" - - internalcontext "github.com/aws/aws-sdk-go-v2/internal/context" - "github.com/aws/smithy-go/middleware" -) - -// AddTimeOffsetMiddleware sets a value representing clock skew on the request context. -// This can be read by other operations (such as signing) to correct the date value they send -// on the request -type AddTimeOffsetMiddleware struct { - Offset *atomic.Int64 -} - -// ID the identifier for AddTimeOffsetMiddleware -func (m *AddTimeOffsetMiddleware) ID() string { return "AddTimeOffsetMiddleware" } - -// HandleBuild sets a value for attemptSkew on the request context if one is set on the client. -func (m AddTimeOffsetMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - if m.Offset != nil { - offset := time.Duration(m.Offset.Load()) - ctx = internalcontext.SetAttemptSkewContext(ctx, offset) - } - return next.HandleBuild(ctx, in) -} - -// HandleDeserialize gets the clock skew context from the context, and if set, sets it on the pointer -// held by AddTimeOffsetMiddleware -func (m *AddTimeOffsetMiddleware) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - if v := internalcontext.GetAttemptSkewContext(ctx); v != 0 { - m.Offset.Store(v.Nanoseconds()) - } - return next.HandleDeserialize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/rand/rand.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/rand/rand.go deleted file mode 100644 index c8484dc..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/rand/rand.go +++ /dev/null @@ -1,33 +0,0 @@ -package rand - -import ( - "crypto/rand" - "fmt" - "io" - "math/big" -) - -func init() { - Reader = rand.Reader -} - -// Reader provides a random reader that can reset during testing. -var Reader io.Reader - -var floatMaxBigInt = big.NewInt(1 << 53) - -// Float64 returns a float64 read from an io.Reader source. The returned float will be between [0.0, 1.0). -func Float64(reader io.Reader) (float64, error) { - bi, err := rand.Int(reader, floatMaxBigInt) - if err != nil { - return 0, fmt.Errorf("failed to read random value, %v", err) - } - - return float64(bi.Int64()) / (1 << 53), nil -} - -// CryptoRandFloat64 returns a random float64 obtained from the crypto rand -// source. -func CryptoRandFloat64() (float64, error) { - return Float64(Reader) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/interfaces.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/interfaces.go deleted file mode 100644 index 2b42cbe..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/interfaces.go +++ /dev/null @@ -1,9 +0,0 @@ -package sdk - -// Invalidator provides access to a type's invalidate method to make it -// invalidate it cache. -// -// e.g aws.SafeCredentialsProvider's Invalidate method. -type Invalidator interface { - Invalidate() -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/time.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/time.go deleted file mode 100644 index 8e8daba..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/time.go +++ /dev/null @@ -1,74 +0,0 @@ -package sdk - -import ( - "context" - "time" -) - -func init() { - NowTime = time.Now - Sleep = time.Sleep - SleepWithContext = sleepWithContext -} - -// NowTime is a value for getting the current time. This value can be overridden -// for testing mocking out current time. -var NowTime func() time.Time - -// Sleep is a value for sleeping for a duration. This value can be overridden -// for testing and mocking out sleep duration. -var Sleep func(time.Duration) - -// SleepWithContext will wait for the timer duration to expire, or the context -// is canceled. Which ever happens first. If the context is canceled the Context's -// error will be returned. -// -// This value can be overridden for testing and mocking out sleep duration. -var SleepWithContext func(context.Context, time.Duration) error - -// sleepWithContext will wait for the timer duration to expire, or the context -// is canceled. Which ever happens first. If the context is canceled the -// Context's error will be returned. -func sleepWithContext(ctx context.Context, dur time.Duration) error { - t := time.NewTimer(dur) - defer t.Stop() - - select { - case <-t.C: - break - case <-ctx.Done(): - return ctx.Err() - } - - return nil -} - -// noOpSleepWithContext does nothing, returns immediately. -func noOpSleepWithContext(context.Context, time.Duration) error { - return nil -} - -func noOpSleep(time.Duration) {} - -// TestingUseNopSleep is a utility for disabling sleep across the SDK for -// testing. -func TestingUseNopSleep() func() { - SleepWithContext = noOpSleepWithContext - Sleep = noOpSleep - - return func() { - SleepWithContext = sleepWithContext - Sleep = time.Sleep - } -} - -// TestingUseReferenceTime is a utility for swapping the time function across the SDK to return a specific reference time -// for testing purposes. -func TestingUseReferenceTime(referenceTime time.Time) func() { - NowTime = func() time.Time { - return referenceTime - } - return func() { - NowTime = time.Now - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/sdkio/byte.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/sdkio/byte.go deleted file mode 100644 index 6c44398..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/sdkio/byte.go +++ /dev/null @@ -1,12 +0,0 @@ -package sdkio - -const ( - // Byte is 8 bits - Byte int64 = 1 - // KibiByte (KiB) is 1024 Bytes - KibiByte = Byte * 1024 - // MebiByte (MiB) is 1024 KiB - MebiByte = KibiByte * 1024 - // GibiByte (GiB) is 1024 MiB - GibiByte = MebiByte * 1024 -) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/shareddefaults/shared_config.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/shareddefaults/shared_config.go deleted file mode 100644 index c96b717..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/shareddefaults/shared_config.go +++ /dev/null @@ -1,47 +0,0 @@ -package shareddefaults - -import ( - "os" - "os/user" - "path/filepath" -) - -// SharedCredentialsFilename returns the SDK's default file path -// for the shared credentials file. -// -// Builds the shared config file path based on the OS's platform. -// -// - Linux/Unix: $HOME/.aws/credentials -// - Windows: %USERPROFILE%\.aws\credentials -func SharedCredentialsFilename() string { - return filepath.Join(UserHomeDir(), ".aws", "credentials") -} - -// SharedConfigFilename returns the SDK's default file path for -// the shared config file. -// -// Builds the shared config file path based on the OS's platform. -// -// - Linux/Unix: $HOME/.aws/config -// - Windows: %USERPROFILE%\.aws\config -func SharedConfigFilename() string { - return filepath.Join(UserHomeDir(), ".aws", "config") -} - -// UserHomeDir returns the home directory for the user the process is -// running under. -func UserHomeDir() string { - // Ignore errors since we only care about Windows and *nix. - home, _ := os.UserHomeDir() - - if len(home) > 0 { - return home - } - - currUser, _ := user.Current() - if currUser != nil { - home = currUser.HomeDir - } - - return home -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/strings/strings.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/strings/strings.go deleted file mode 100644 index d008ae2..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/strings/strings.go +++ /dev/null @@ -1,11 +0,0 @@ -package strings - -import ( - "strings" -) - -// HasPrefixFold tests whether the string s begins with prefix, interpreted as UTF-8 strings, -// under Unicode case-folding. -func HasPrefixFold(s, prefix string) bool { - return len(s) >= len(prefix) && strings.EqualFold(s[0:len(prefix)], prefix) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/LICENSE b/vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/LICENSE deleted file mode 100644 index fe6a620..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -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 COPYIGHT 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/vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/docs.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/docs.go deleted file mode 100644 index cb70616..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/docs.go +++ /dev/null @@ -1,7 +0,0 @@ -// Package singleflight provides a duplicate function call suppression -// mechanism. This package is a fork of the Go golang.org/x/sync/singleflight -// package. The package is forked, because the package a part of the unstable -// and unversioned golang.org/x/sync module. -// -// https://github.com/golang/sync/tree/67f06af15bc961c363a7260195bcd53487529a21/singleflight -package singleflight diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/singleflight.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/singleflight.go deleted file mode 100644 index e8a1b17..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/singleflight.go +++ /dev/null @@ -1,210 +0,0 @@ -// 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. - -package singleflight - -import ( - "bytes" - "errors" - "fmt" - "runtime" - "runtime/debug" - "sync" -) - -// errGoexit indicates the runtime.Goexit was called in -// the user given function. -var errGoexit = errors.New("runtime.Goexit was called") - -// A panicError is an arbitrary value recovered from a panic -// with the stack trace during the execution of given function. -type panicError struct { - value interface{} - stack []byte -} - -// Error implements error interface. -func (p *panicError) Error() string { - return fmt.Sprintf("%v\n\n%s", p.value, p.stack) -} - -func newPanicError(v interface{}) error { - stack := debug.Stack() - - // The first line of the stack trace is of the form "goroutine N [status]:" - // but by the time the panic reaches Do the goroutine may no longer exist - // and its status will have changed. Trim out the misleading line. - if line := bytes.IndexByte(stack[:], '\n'); line >= 0 { - stack = stack[line+1:] - } - return &panicError{value: v, stack: stack} -} - -// call is an in-flight or completed singleflight.Do call -type call struct { - wg sync.WaitGroup - - // These fields are written once before the WaitGroup is done - // and are only read after the WaitGroup is done. - val interface{} - err error - - // forgotten indicates whether Forget was called with this call's key - // while the call was still in flight. - forgotten bool - - // These fields are read and written with the singleflight - // mutex held before the WaitGroup is done, and are read but - // not written after the WaitGroup is done. - dups int - chans []chan<- Result -} - -// Group represents a class of work and forms a namespace in -// which units of work can be executed with duplicate suppression. -type Group struct { - mu sync.Mutex // protects m - m map[string]*call // lazily initialized -} - -// Result holds the results of Do, so they can be passed -// on a channel. -type Result struct { - Val interface{} - Err error - Shared bool -} - -// Do executes and returns the results of the given function, making -// sure that only one execution is in-flight for a given key at a -// time. If a duplicate comes in, the duplicate caller waits for the -// original to complete and receives the same results. -// The return value shared indicates whether v was given to multiple callers. -func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) { - g.mu.Lock() - if g.m == nil { - g.m = make(map[string]*call) - } - if c, ok := g.m[key]; ok { - c.dups++ - g.mu.Unlock() - c.wg.Wait() - - if e, ok := c.err.(*panicError); ok { - panic(e) - } else if c.err == errGoexit { - runtime.Goexit() - } - return c.val, c.err, true - } - c := new(call) - c.wg.Add(1) - g.m[key] = c - g.mu.Unlock() - - g.doCall(c, key, fn) - return c.val, c.err, c.dups > 0 -} - -// DoChan is like Do but returns a channel that will receive the -// results when they are ready. -// -// The returned channel will not be closed. -func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result { - ch := make(chan Result, 1) - g.mu.Lock() - if g.m == nil { - g.m = make(map[string]*call) - } - if c, ok := g.m[key]; ok { - c.dups++ - c.chans = append(c.chans, ch) - g.mu.Unlock() - return ch - } - c := &call{chans: []chan<- Result{ch}} - c.wg.Add(1) - g.m[key] = c - g.mu.Unlock() - - go g.doCall(c, key, fn) - - return ch -} - -// doCall handles the single call for a key. -func (g *Group) doCall(c *call, key string, fn func() (interface{}, error)) { - normalReturn := false - recovered := false - - // use double-defer to distinguish panic from runtime.Goexit, - // more details see https://golang.org/cl/134395 - defer func() { - // the given function invoked runtime.Goexit - if !normalReturn && !recovered { - c.err = errGoexit - } - - c.wg.Done() - g.mu.Lock() - defer g.mu.Unlock() - if !c.forgotten { - delete(g.m, key) - } - - if e, ok := c.err.(*panicError); ok { - // In order to prevent the waiting channels from being blocked forever, - // needs to ensure that this panic cannot be recovered. - if len(c.chans) > 0 { - go panic(e) - select {} // Keep this goroutine around so that it will appear in the crash dump. - } else { - panic(e) - } - } else if c.err == errGoexit { - // Already in the process of goexit, no need to call again - } else { - // Normal return - for _, ch := range c.chans { - ch <- Result{c.val, c.err, c.dups > 0} - } - } - }() - - func() { - defer func() { - if !normalReturn { - // Ideally, we would wait to take a stack trace until we've determined - // whether this is a panic or a runtime.Goexit. - // - // Unfortunately, the only way we can distinguish the two is to see - // whether the recover stopped the goroutine from terminating, and by - // the time we know that, the part of the stack trace relevant to the - // panic has been discarded. - if r := recover(); r != nil { - c.err = newPanicError(r) - } - } - }() - - c.val, c.err = fn() - normalReturn = true - }() - - if !normalReturn { - recovered = true - } -} - -// Forget tells the singleflight to forget about a key. Future calls -// to Do for this key will call the function rather than waiting for -// an earlier call to complete. -func (g *Group) Forget(key string) { - g.mu.Lock() - if c, ok := g.m[key]; ok { - c.forgotten = true - } - delete(g.m, key) - g.mu.Unlock() -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/timeconv/duration.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/timeconv/duration.go deleted file mode 100644 index 5d69db5..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/timeconv/duration.go +++ /dev/null @@ -1,13 +0,0 @@ -package timeconv - -import "time" - -// FloatSecondsDur converts a fractional seconds to duration. -func FloatSecondsDur(v float64) time.Duration { - return time.Duration(v * float64(time.Second)) -} - -// DurSecondsFloat converts a duration into fractional seconds. -func DurSecondsFloat(d time.Duration) float64 { - return float64(d) / float64(time.Second) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md deleted file mode 100644 index 6ffbf3f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md +++ /dev/null @@ -1,188 +0,0 @@ -# v1.13.4 (2025-12-02) - -* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. - -# v1.13.3 (2025-11-04) - -* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. - -# v1.13.2 (2025-10-16) - -* **Dependency Update**: Bump minimum Go version to 1.23. - -# v1.13.1 (2025-08-27) - -* **Dependency Update**: Update to smithy-go v1.23.0. - -# v1.13.0 (2025-07-28) - -* **Feature**: Add support for HTTP interceptors. - -# v1.12.4 (2025-06-17) - -* **Dependency Update**: Update to smithy-go v1.22.4. - -# v1.12.3 (2025-02-18) - -* **Bug Fix**: Bump go version to 1.22 - -# v1.12.2 (2025-01-24) - -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v1.12.1 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. - -# v1.12.0 (2024-10-04) - -* **Feature**: Add support for HTTP client metrics. - -# v1.11.5 (2024-09-20) - -* No change notes available for this release. - -# v1.11.4 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. - -# v1.11.3 (2024-06-28) - -* No change notes available for this release. - -# v1.11.2 (2024-03-29) - -* No change notes available for this release. - -# v1.11.1 (2024-02-21) - -* No change notes available for this release. - -# v1.11.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. - -# v1.10.4 (2023-12-07) - -* No change notes available for this release. - -# v1.10.3 (2023-11-30) - -* No change notes available for this release. - -# v1.10.2 (2023-11-29) - -* No change notes available for this release. - -# v1.10.1 (2023-11-15) - -* No change notes available for this release. - -# v1.10.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). - -# v1.9.15 (2023-10-06) - -* No change notes available for this release. - -# v1.9.14 (2023-08-18) - -* No change notes available for this release. - -# v1.9.13 (2023-08-07) - -* No change notes available for this release. - -# v1.9.12 (2023-07-31) - -* No change notes available for this release. - -# v1.9.11 (2022-12-02) - -* No change notes available for this release. - -# v1.9.10 (2022-10-24) - -* No change notes available for this release. - -# v1.9.9 (2022-09-14) - -* No change notes available for this release. - -# v1.9.8 (2022-09-02) - -* No change notes available for this release. - -# v1.9.7 (2022-08-31) - -* No change notes available for this release. - -# v1.9.6 (2022-08-29) - -* No change notes available for this release. - -# v1.9.5 (2022-08-11) - -* No change notes available for this release. - -# v1.9.4 (2022-08-09) - -* No change notes available for this release. - -# v1.9.3 (2022-06-29) - -* No change notes available for this release. - -# v1.9.2 (2022-06-07) - -* No change notes available for this release. - -# v1.9.1 (2022-03-24) - -* No change notes available for this release. - -# v1.9.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version - -# v1.8.0 (2022-02-24) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version - -# v1.7.0 (2022-01-14) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version - -# v1.6.0 (2022-01-07) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version - -# v1.5.0 (2021-11-06) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version - -# v1.4.0 (2021-10-21) - -* **Feature**: Updated to latest version - -# v1.3.0 (2021-08-27) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version - -# v1.2.2 (2021-08-04) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version. - -# v1.2.1 (2021-07-15) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version - -# v1.2.0 (2021-06-25) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version - -# v1.1.0 (2021-05-14) - -* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting. - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/accept_encoding_gzip.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/accept_encoding_gzip.go deleted file mode 100644 index 3f451fc..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/accept_encoding_gzip.go +++ /dev/null @@ -1,176 +0,0 @@ -package acceptencoding - -import ( - "compress/gzip" - "context" - "fmt" - "io" - - "github.com/aws/smithy-go" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -const acceptEncodingHeaderKey = "Accept-Encoding" -const contentEncodingHeaderKey = "Content-Encoding" - -// AddAcceptEncodingGzipOptions provides the options for the -// AddAcceptEncodingGzip middleware setup. -type AddAcceptEncodingGzipOptions struct { - Enable bool -} - -// AddAcceptEncodingGzip explicitly adds handling for accept-encoding GZIP -// middleware to the operation stack. This allows checksums to be correctly -// computed without disabling GZIP support. -func AddAcceptEncodingGzip(stack *middleware.Stack, options AddAcceptEncodingGzipOptions) error { - if options.Enable { - if err := stack.Finalize.Add(&EnableGzip{}, middleware.Before); err != nil { - return err - } - if err := stack.Deserialize.Insert(&DecompressGzip{}, "OperationDeserializer", middleware.After); err != nil { - return err - } - return nil - } - - return stack.Finalize.Add(&DisableGzip{}, middleware.Before) -} - -// DisableGzip provides the middleware that will -// disable the underlying http client automatically enabling for gzip -// decompress content-encoding support. -type DisableGzip struct{} - -// ID returns the id for the middleware. -func (*DisableGzip) ID() string { - return "DisableAcceptEncodingGzip" -} - -// HandleFinalize implements the FinalizeMiddleware interface. -func (*DisableGzip) HandleFinalize( - ctx context.Context, input middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - output middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := input.Request.(*smithyhttp.Request) - if !ok { - return output, metadata, &smithy.SerializationError{ - Err: fmt.Errorf("unknown request type %T", input.Request), - } - } - - // Explicitly enable gzip support, this will prevent the http client from - // auto extracting the zipped content. - req.Header.Set(acceptEncodingHeaderKey, "identity") - - return next.HandleFinalize(ctx, input) -} - -// EnableGzip provides a middleware to enable support for -// gzip responses, with manual decompression. This prevents the underlying HTTP -// client from performing the gzip decompression automatically. -type EnableGzip struct{} - -// ID returns the id for the middleware. -func (*EnableGzip) ID() string { - return "AcceptEncodingGzip" -} - -// HandleFinalize implements the FinalizeMiddleware interface. -func (*EnableGzip) HandleFinalize( - ctx context.Context, input middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - output middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := input.Request.(*smithyhttp.Request) - if !ok { - return output, metadata, &smithy.SerializationError{ - Err: fmt.Errorf("unknown request type %T", input.Request), - } - } - - // Explicitly enable gzip support, this will prevent the http client from - // auto extracting the zipped content. - req.Header.Set(acceptEncodingHeaderKey, "gzip") - - return next.HandleFinalize(ctx, input) -} - -// DecompressGzip provides the middleware for decompressing a gzip -// response from the service. -type DecompressGzip struct{} - -// ID returns the id for the middleware. -func (*DecompressGzip) ID() string { - return "DecompressGzip" -} - -// HandleDeserialize implements the DeserializeMiddlware interface. -func (*DecompressGzip) HandleDeserialize( - ctx context.Context, input middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - output middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - output, metadata, err = next.HandleDeserialize(ctx, input) - if err != nil { - return output, metadata, err - } - - resp, ok := output.RawResponse.(*smithyhttp.Response) - if !ok { - return output, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("unknown response type %T", output.RawResponse), - } - } - if v := resp.Header.Get(contentEncodingHeaderKey); v != "gzip" { - return output, metadata, err - } - - // Clear content length since it will no longer be valid once the response - // body is decompressed. - resp.Header.Del("Content-Length") - resp.ContentLength = -1 - - resp.Body = wrapGzipReader(resp.Body) - - return output, metadata, err -} - -type gzipReader struct { - reader io.ReadCloser - gzip *gzip.Reader -} - -func wrapGzipReader(reader io.ReadCloser) *gzipReader { - return &gzipReader{ - reader: reader, - } -} - -// Read wraps the gzip reader around the underlying io.Reader to extract the -// response bytes on the fly. -func (g *gzipReader) Read(b []byte) (n int, err error) { - if g.gzip == nil { - g.gzip, err = gzip.NewReader(g.reader) - if err != nil { - g.gzip = nil // ensure uninitialized gzip value isn't used in close. - return 0, fmt.Errorf("failed to decompress gzip response, %w", err) - } - } - - return g.gzip.Read(b) -} - -func (g *gzipReader) Close() error { - if g.gzip == nil { - return nil - } - - if err := g.gzip.Close(); err != nil { - g.reader.Close() - return fmt.Errorf("failed to decompress gzip response, %w", err) - } - - return g.reader.Close() -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/doc.go deleted file mode 100644 index 7056d9b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -/* -Package acceptencoding provides customizations associated with Accept Encoding Header. - -# Accept encoding gzip - -The Go HTTP client automatically supports accept-encoding and content-encoding -gzip by default. This default behavior is not desired by the SDK, and prevents -validating the response body's checksum. To prevent this the SDK must manually -control usage of content-encoding gzip. - -To control content-encoding, the SDK must always set the `Accept-Encoding` -header to a value. This prevents the HTTP client from using gzip automatically. -When gzip is enabled on the API client, the SDK's customization will control -decompressing the gzip data in order to not break the checksum validation. When -gzip is disabled, the API client will disable gzip, preventing the HTTP -client's default behavior. - -An `EnableAcceptEncodingGzip` option may or may not be present depending on the client using -the below middleware. The option if present can be used to enable auto decompressing -gzip by the SDK. -*/ -package acceptencoding diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go deleted file mode 100644 index 970bb21..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package acceptencoding - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.13.4" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md deleted file mode 100644 index 743183c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md +++ /dev/null @@ -1,513 +0,0 @@ -# v1.13.16 (2025-12-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.15 (2025-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. - -# v1.13.14 (2025-11-19.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.13 (2025-11-04) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. - -# v1.13.12 (2025-10-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.11 (2025-10-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.10 (2025-10-16) - -* **Dependency Update**: Bump minimum Go version to 1.23. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.9 (2025-09-26) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.8 (2025-09-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.7 (2025-09-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.6 (2025-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.5 (2025-08-27) - -* **Dependency Update**: Update to smithy-go v1.23.0. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.4 (2025-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.3 (2025-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.2 (2025-08-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.1 (2025-07-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.0 (2025-07-28) - -* **Feature**: Add support for HTTP interceptors. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.18 (2025-07-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.17 (2025-06-17) - -* **Dependency Update**: Update to smithy-go v1.22.4. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.16 (2025-06-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.15 (2025-02-27) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.14 (2025-02-18) - -* **Bug Fix**: Bump go version to 1.22 -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.13 (2025-02-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.12 (2025-01-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.11 (2025-01-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.10 (2025-01-24) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v1.12.9 (2025-01-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.8 (2025-01-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.7 (2024-12-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.6 (2024-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.5 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.4 (2024-11-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.3 (2024-10-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.2 (2024-10-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.1 (2024-10-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.0 (2024-10-04) - -* **Feature**: Add support for HTTP client metrics. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.20 (2024-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.19 (2024-09-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.18 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.17 (2024-07-10.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.16 (2024-07-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.15 (2024-06-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.14 (2024-06-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.13 (2024-06-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.12 (2024-06-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.11 (2024-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.10 (2024-06-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.9 (2024-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.8 (2024-05-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.7 (2024-03-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.6 (2024-03-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.5 (2024-03-07) - -* **Bug Fix**: Remove dependency on go-cmp. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.4 (2024-03-05) - -* **Bug Fix**: Restore typo'd API `AddAsIsInternalPresigingMiddleware` as an alias for backwards compatibility. - -# v1.11.3 (2024-03-04) - -* **Bug Fix**: Correct a typo in internal AddAsIsPresigningMiddleware API. - -# v1.11.2 (2024-02-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.1 (2024-02-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.10 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.9 (2023-12-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.8 (2023-12-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.7 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.6 (2023-11-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.5 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.4 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.3 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.2 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.1 (2023-11-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.37 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.36 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.35 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.34 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.33 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.32 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.31 (2023-07-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.30 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.29 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.28 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.27 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.26 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.25 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.24 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.23 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.22 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.21 (2022-12-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.20 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.19 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.18 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.17 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.16 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.15 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.14 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.13 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.12 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.11 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.10 (2022-08-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.9 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.8 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.7 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.6 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.5 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.4 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.3 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.2 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.1 (2022-03-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.0 (2022-02-24) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.7.0 (2022-01-14) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.0 (2022-01-07) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.2 (2021-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.1 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.0 (2021-11-06) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.0 (2021-10-21) - -* **Feature**: Updated to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.2 (2021-10-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.1 (2021-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.0 (2021-08-27) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.3 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.2 (2021-08-04) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.1 (2021-07-15) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.0 (2021-06-25) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.1 (2021-05-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.1.0 (2021-05-14) - -* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting. -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/context.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/context.go deleted file mode 100644 index 5d5286f..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/context.go +++ /dev/null @@ -1,56 +0,0 @@ -package presignedurl - -import ( - "context" - - "github.com/aws/smithy-go/middleware" -) - -// WithIsPresigning adds the isPresigning sentinel value to a context to signal -// that the middleware stack is using the presign flow. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func WithIsPresigning(ctx context.Context) context.Context { - return middleware.WithStackValue(ctx, isPresigningKey{}, true) -} - -// GetIsPresigning returns if the context contains the isPresigning sentinel -// value for presigning flows. -// -// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues -// to clear all stack values. -func GetIsPresigning(ctx context.Context) bool { - v, _ := middleware.GetStackValue(ctx, isPresigningKey{}).(bool) - return v -} - -type isPresigningKey struct{} - -// AddAsIsPresigningMiddleware adds a middleware to the head of the stack that -// will update the stack's context to be flagged as being invoked for the -// purpose of presigning. -func AddAsIsPresigningMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(asIsPresigningMiddleware{}, middleware.Before) -} - -// AddAsIsPresigingMiddleware is an alias for backwards compatibility. -// -// Deprecated: This API was released with a typo. Use -// [AddAsIsPresigningMiddleware] instead. -func AddAsIsPresigingMiddleware(stack *middleware.Stack) error { - return AddAsIsPresigningMiddleware(stack) -} - -type asIsPresigningMiddleware struct{} - -func (asIsPresigningMiddleware) ID() string { return "AsIsPresigningMiddleware" } - -func (asIsPresigningMiddleware) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - ctx = WithIsPresigning(ctx) - return next.HandleInitialize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/doc.go deleted file mode 100644 index 1b85375..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package presignedurl provides the customizations for API clients to fill in -// presigned URLs into input parameters. -package presignedurl diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go deleted file mode 100644 index a8a2e69..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package presignedurl - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.13.16" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/middleware.go deleted file mode 100644 index 1e2f5c8..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/middleware.go +++ /dev/null @@ -1,110 +0,0 @@ -package presignedurl - -import ( - "context" - "fmt" - - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - - "github.com/aws/smithy-go/middleware" -) - -// URLPresigner provides the interface to presign the input parameters in to a -// presigned URL. -type URLPresigner interface { - // PresignURL presigns a URL. - PresignURL(ctx context.Context, srcRegion string, params interface{}) (*v4.PresignedHTTPRequest, error) -} - -// ParameterAccessor provides an collection of accessor to for retrieving and -// setting the values needed to PresignedURL generation -type ParameterAccessor struct { - // GetPresignedURL accessor points to a function that retrieves a presigned url if present - GetPresignedURL func(interface{}) (string, bool, error) - - // GetSourceRegion accessor points to a function that retrieves source region for presigned url - GetSourceRegion func(interface{}) (string, bool, error) - - // CopyInput accessor points to a function that takes in an input, and returns a copy. - CopyInput func(interface{}) (interface{}, error) - - // SetDestinationRegion accessor points to a function that sets destination region on api input struct - SetDestinationRegion func(interface{}, string) error - - // SetPresignedURL accessor points to a function that sets presigned url on api input struct - SetPresignedURL func(interface{}, string) error -} - -// Options provides the set of options needed by the presigned URL middleware. -type Options struct { - // Accessor are the parameter accessors used by this middleware - Accessor ParameterAccessor - - // Presigner is the URLPresigner used by the middleware - Presigner URLPresigner -} - -// AddMiddleware adds the Presign URL middleware to the middleware stack. -func AddMiddleware(stack *middleware.Stack, opts Options) error { - return stack.Initialize.Add(&presign{options: opts}, middleware.Before) -} - -// RemoveMiddleware removes the Presign URL middleware from the stack. -func RemoveMiddleware(stack *middleware.Stack) error { - _, err := stack.Initialize.Remove((*presign)(nil).ID()) - return err -} - -type presign struct { - options Options -} - -func (m *presign) ID() string { return "Presign" } - -func (m *presign) HandleInitialize( - ctx context.Context, input middleware.InitializeInput, next middleware.InitializeHandler, -) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - // If PresignedURL is already set ignore middleware. - if _, ok, err := m.options.Accessor.GetPresignedURL(input.Parameters); err != nil { - return out, metadata, fmt.Errorf("presign middleware failed, %w", err) - } else if ok { - return next.HandleInitialize(ctx, input) - } - - // If have source region is not set ignore middleware. - srcRegion, ok, err := m.options.Accessor.GetSourceRegion(input.Parameters) - if err != nil { - return out, metadata, fmt.Errorf("presign middleware failed, %w", err) - } else if !ok || len(srcRegion) == 0 { - return next.HandleInitialize(ctx, input) - } - - // Create a copy of the original input so the destination region value can - // be added. This ensures that value does not leak into the original - // request parameters. - paramCpy, err := m.options.Accessor.CopyInput(input.Parameters) - if err != nil { - return out, metadata, fmt.Errorf("unable to create presigned URL, %w", err) - } - - // Destination region is the API client's configured region. - dstRegion := awsmiddleware.GetRegion(ctx) - if err = m.options.Accessor.SetDestinationRegion(paramCpy, dstRegion); err != nil { - return out, metadata, fmt.Errorf("presign middleware failed, %w", err) - } - - presignedReq, err := m.options.Presigner.PresignURL(ctx, srcRegion, paramCpy) - if err != nil { - return out, metadata, fmt.Errorf("unable to create presigned URL, %w", err) - } - - // Update the original input with the presigned URL value. - if err = m.options.Accessor.SetPresignedURL(input.Parameters, presignedReq.URL); err != nil { - return out, metadata, fmt.Errorf("presign middleware failed, %w", err) - } - - return next.HandleInitialize(ctx, input) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md deleted file mode 100644 index 8a05d96..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md +++ /dev/null @@ -1,576 +0,0 @@ -# v1.24.14 (2025-01-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.13 (2025-01-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.12 (2025-01-24) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v1.24.11 (2025-01-17) - -* **Bug Fix**: Fix bug where credentials weren't refreshed during retry loop. - -# v1.24.10 (2025-01-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.9 (2025-01-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.8 (2024-12-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.7 (2024-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.6 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.5 (2024-11-07) - -* **Bug Fix**: Adds case-insensitive handling of error message fields in service responses - -# v1.24.4 (2024-11-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.3 (2024-10-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.2 (2024-10-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.1 (2024-10-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.0 (2024-10-04) - -* **Feature**: Add support for HTTP client metrics. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.4 (2024-10-03) - -* No change notes available for this release. - -# v1.23.3 (2024-09-27) - -* No change notes available for this release. - -# v1.23.2 (2024-09-25) - -* No change notes available for this release. - -# v1.23.1 (2024-09-23) - -* No change notes available for this release. - -# v1.23.0 (2024-09-20) - -* **Feature**: Add tracing and metrics support to service clients. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.8 (2024-09-17) - -* **Bug Fix**: **BREAKFIX**: Only generate AccountIDEndpointMode config for services that use it. This is a compiler break, but removes no actual functionality, as no services currently use the account ID in endpoint resolution. - -# v1.22.7 (2024-09-04) - -* No change notes available for this release. - -# v1.22.6 (2024-09-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.5 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.4 (2024-07-18) - -* No change notes available for this release. - -# v1.22.3 (2024-07-10.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.2 (2024-07-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.1 (2024-06-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.0 (2024-06-26) - -* **Feature**: Support list-of-string endpoint parameter. - -# v1.21.1 (2024-06-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.0 (2024-06-18) - -* **Feature**: Track usage of various AWS SDK features in user-agent string. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.12 (2024-06-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.11 (2024-06-07) - -* **Bug Fix**: Add clock skew correction on all service clients -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.10 (2024-06-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.9 (2024-05-23) - -* No change notes available for this release. - -# v1.20.8 (2024-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.7 (2024-05-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.6 (2024-05-08) - -* **Bug Fix**: GoDoc improvement - -# v1.20.5 (2024-04-05) - -* No change notes available for this release. - -# v1.20.4 (2024-03-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.3 (2024-03-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.2 (2024-03-07) - -* **Bug Fix**: Remove dependency on go-cmp. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.1 (2024-02-23) - -* **Bug Fix**: Move all common, SDK-side middleware stack ops into the service client module to prevent cross-module compatibility issues in the future. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.0 (2024-02-22) - -* **Feature**: Add middleware stack snapshot tests. - -# v1.19.2 (2024-02-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.19.1 (2024-02-20) - -* **Bug Fix**: When sourcing values for a service's `EndpointParameters`, the lack of a configured region (i.e. `options.Region == ""`) will now translate to a `nil` value for `EndpointParameters.Region` instead of a pointer to the empty string `""`. This will result in a much more explicit error when calling an operation instead of an obscure hostname lookup failure. - -# v1.19.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.7 (2024-01-18) - -* No change notes available for this release. - -# v1.18.6 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.5 (2023-12-08) - -* **Bug Fix**: Reinstate presence of default Retryer in functional options, but still respect max attempts set therein. - -# v1.18.4 (2023-12-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.3 (2023-12-06) - -* **Bug Fix**: Restore pre-refactor auth behavior where all operations could technically be performed anonymously. - -# v1.18.2 (2023-12-01) - -* **Bug Fix**: Correct wrapping of errors in authentication workflow. -* **Bug Fix**: Correctly recognize cache-wrapped instances of AnonymousCredentials at client construction. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.1 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.0 (2023-11-29) - -* **Feature**: Expose Options() accessor on service clients. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.5 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.4 (2023-11-28) - -* **Bug Fix**: Respect setting RetryMaxAttempts in functional options at client construction. - -# v1.17.3 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.2 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.1 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.0 (2023-11-01) - -* **Feature**: Adds support for configured endpoints via environment variables and the AWS shared configuration file. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.2 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.1 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.0 (2023-10-02) - -* **Feature**: Fix FIPS Endpoints in aws-us-gov. - -# v1.14.1 (2023-09-22) - -* No change notes available for this release. - -# v1.14.0 (2023-09-18) - -* **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. -* **Feature**: Adds several endpoint ruleset changes across all models: smaller rulesets, removed non-unique regional endpoints, fixes FIPS and DualStack endpoints, and make region not required in SDK::Endpoint. Additional breakfix to cognito-sync field. - -# v1.13.6 (2023-08-31) - -* No change notes available for this release. - -# v1.13.5 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.4 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.3 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.2 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.1 (2023-08-01) - -* No change notes available for this release. - -# v1.13.0 (2023-07-31) - -* **Feature**: Adds support for smithy-modeled endpoint resolution. A new rules-based endpoint resolution will be added to the SDK which will supercede and deprecate existing endpoint resolution. Specifically, EndpointResolver will be deprecated while BaseEndpoint and EndpointResolverV2 will take its place. For more information, please see the Endpoints section in our Developer Guide. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.14 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.13 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.12 (2023-06-15) - -* No change notes available for this release. - -# v1.12.11 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.10 (2023-05-04) - -* No change notes available for this release. - -# v1.12.9 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.8 (2023-04-10) - -* No change notes available for this release. - -# v1.12.7 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.6 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.5 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.4 (2023-02-22) - -* **Bug Fix**: Prevent nil pointer dereference when retrieving error codes. - -# v1.12.3 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.2 (2023-02-15) - -* **Announcement**: When receiving an error response in restJson-based services, an incorrect error type may have been returned based on the content of the response. This has been fixed via PR #2012 tracked in issue #1910. -* **Bug Fix**: Correct error type parsing for restJson services. - -# v1.12.1 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.0 (2023-01-05) - -* **Feature**: Add `ErrorCodeOverride` field to all error structs (aws/smithy-go#401). - -# v1.11.28 (2022-12-20) - -* No change notes available for this release. - -# v1.11.27 (2022-12-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.26 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.25 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.24 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.23 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.22 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.21 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.20 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.19 (2022-08-30) - -* **Documentation**: Documentation updates for the AWS IAM Identity Center Portal CLI Reference. - -# v1.11.18 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.17 (2022-08-15) - -* **Documentation**: Documentation updates to reflect service rename - AWS IAM Identity Center (successor to AWS Single Sign-On) - -# v1.11.16 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.15 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.14 (2022-08-08) - -* **Documentation**: Documentation updates to reflect service rename - AWS IAM Identity Center (successor to AWS Single Sign-On) -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.13 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.12 (2022-07-11) - -* No change notes available for this release. - -# v1.11.11 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.10 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.9 (2022-06-16) - -* No change notes available for this release. - -# v1.11.8 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.7 (2022-05-26) - -* No change notes available for this release. - -# v1.11.6 (2022-05-25) - -* No change notes available for this release. - -# v1.11.5 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.4 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.3 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.2 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.1 (2022-03-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.0 (2022-02-24) - -* **Feature**: API client updated -* **Feature**: Adds RetryMaxAttempts and RetryMod to API client Options. This allows the API clients' default Retryer to be configured from the shared configuration files or environment variables. Adding a new Retry mode of `Adaptive`. `Adaptive` retry mode is an experimental mode, adding client rate limiting when throttles reponses are received from an API. See [retry.AdaptiveMode](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AdaptiveMode) for more details, and configuration options. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.0 (2022-01-14) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Documentation**: Updated API models -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.0 (2022-01-07) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.7.0 (2021-12-21) - -* **Feature**: API Paginators now support specifying the initial starting token, and support stopping on empty string tokens. - -# v1.6.2 (2021-12-02) - -* **Bug Fix**: Fixes a bug that prevented aws.EndpointResolverWithOptions from being used by the service client. ([#1514](https://github.com/aws/aws-sdk-go-v2/pull/1514)) -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.1 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.0 (2021-11-06) - -* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Feature**: Updated service to latest API model. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.0 (2021-10-21) - -* **Feature**: Updated to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.2 (2021-10-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.1 (2021-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.0 (2021-08-27) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.3 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.2 (2021-08-04) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.1 (2021-07-15) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.0 (2021-06-25) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.1 (2021-05-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.0 (2021-05-14) - -* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting. -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go deleted file mode 100644 index 0b244f1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go +++ /dev/null @@ -1,912 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "errors" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/aws/defaults" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/retry" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" - internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" - internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" - internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" - internalmiddleware "github.com/aws/aws-sdk-go-v2/internal/middleware" - smithy "github.com/aws/smithy-go" - smithyauth "github.com/aws/smithy-go/auth" - smithydocument "github.com/aws/smithy-go/document" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net" - "net/http" - "sync/atomic" - "time" -) - -const ServiceID = "SSO" -const ServiceAPIVersion = "2019-06-10" - -type operationMetrics struct { - Duration metrics.Float64Histogram - SerializeDuration metrics.Float64Histogram - ResolveIdentityDuration metrics.Float64Histogram - ResolveEndpointDuration metrics.Float64Histogram - SignRequestDuration metrics.Float64Histogram - DeserializeDuration metrics.Float64Histogram -} - -func (m *operationMetrics) histogramFor(name string) metrics.Float64Histogram { - switch name { - case "client.call.duration": - return m.Duration - case "client.call.serialization_duration": - return m.SerializeDuration - case "client.call.resolve_identity_duration": - return m.ResolveIdentityDuration - case "client.call.resolve_endpoint_duration": - return m.ResolveEndpointDuration - case "client.call.signing_duration": - return m.SignRequestDuration - case "client.call.deserialization_duration": - return m.DeserializeDuration - default: - panic("unrecognized operation metric") - } -} - -func timeOperationMetric[T any]( - ctx context.Context, metric string, fn func() (T, error), - opts ...metrics.RecordMetricOption, -) (T, error) { - instr := getOperationMetrics(ctx).histogramFor(metric) - opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) - - start := time.Now() - v, err := fn() - end := time.Now() - - elapsed := end.Sub(start) - instr.Record(ctx, float64(elapsed)/1e9, opts...) - return v, err -} - -func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() { - instr := getOperationMetrics(ctx).histogramFor(metric) - opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) - - var ended bool - start := time.Now() - return func() { - if ended { - return - } - ended = true - - end := time.Now() - - elapsed := end.Sub(start) - instr.Record(ctx, float64(elapsed)/1e9, opts...) - } -} - -func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { - return func(o *metrics.RecordMetricOptions) { - o.Properties.Set("rpc.service", middleware.GetServiceID(ctx)) - o.Properties.Set("rpc.method", middleware.GetOperationName(ctx)) - } -} - -type operationMetricsKey struct{} - -func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) { - meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/sso") - om := &operationMetrics{} - - var err error - - om.Duration, err = operationMetricTimer(meter, "client.call.duration", - "Overall call duration (including retries and time to send or receive request and response body)") - if err != nil { - return nil, err - } - om.SerializeDuration, err = operationMetricTimer(meter, "client.call.serialization_duration", - "The time it takes to serialize a message body") - if err != nil { - return nil, err - } - om.ResolveIdentityDuration, err = operationMetricTimer(meter, "client.call.auth.resolve_identity_duration", - "The time taken to acquire an identity (AWS credentials, bearer token, etc) from an Identity Provider") - if err != nil { - return nil, err - } - om.ResolveEndpointDuration, err = operationMetricTimer(meter, "client.call.resolve_endpoint_duration", - "The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request") - if err != nil { - return nil, err - } - om.SignRequestDuration, err = operationMetricTimer(meter, "client.call.auth.signing_duration", - "The time it takes to sign a request") - if err != nil { - return nil, err - } - om.DeserializeDuration, err = operationMetricTimer(meter, "client.call.deserialization_duration", - "The time it takes to deserialize a message body") - if err != nil { - return nil, err - } - - return context.WithValue(parent, operationMetricsKey{}, om), nil -} - -func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Histogram, error) { - return m.Float64Histogram(name, func(o *metrics.InstrumentOptions) { - o.UnitLabel = "s" - o.Description = desc - }) -} - -func getOperationMetrics(ctx context.Context) *operationMetrics { - return ctx.Value(operationMetricsKey{}).(*operationMetrics) -} - -func operationTracer(p tracing.TracerProvider) tracing.Tracer { - return p.Tracer("github.com/aws/aws-sdk-go-v2/service/sso") -} - -// Client provides the API client to make operations call for AWS Single Sign-On. -type Client struct { - options Options - - // Difference between the time reported by the server and the client - timeOffset *atomic.Int64 -} - -// New returns an initialized Client based on the functional options. Provide -// additional functional options to further configure the behavior of the client, -// such as changing the client's endpoint or adding custom middleware behavior. -func New(options Options, optFns ...func(*Options)) *Client { - options = options.Copy() - - resolveDefaultLogger(&options) - - setResolvedDefaultsMode(&options) - - resolveRetryer(&options) - - resolveHTTPClient(&options) - - resolveHTTPSignerV4(&options) - - resolveEndpointResolverV2(&options) - - resolveTracerProvider(&options) - - resolveMeterProvider(&options) - - resolveAuthSchemeResolver(&options) - - for _, fn := range optFns { - fn(&options) - } - - finalizeRetryMaxAttempts(&options) - - ignoreAnonymousAuth(&options) - - wrapWithAnonymousAuth(&options) - - resolveAuthSchemes(&options) - - client := &Client{ - options: options, - } - - initializeTimeOffsetResolver(client) - - return client -} - -// Options returns a copy of the client configuration. -// -// Callers SHOULD NOT perform mutations on any inner structures within client -// config. Config overrides should instead be made on a per-operation basis through -// functional options. -func (c *Client) Options() Options { - return c.options.Copy() -} - -func (c *Client) invokeOperation( - ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error, -) ( - result interface{}, metadata middleware.Metadata, err error, -) { - ctx = middleware.ClearStackValues(ctx) - ctx = middleware.WithServiceID(ctx, ServiceID) - ctx = middleware.WithOperationName(ctx, opID) - - stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) - options := c.options.Copy() - - for _, fn := range optFns { - fn(&options) - } - - finalizeOperationRetryMaxAttempts(&options, *c) - - finalizeClientEndpointResolverOptions(&options) - - for _, fn := range stackFns { - if err := fn(stack, options); err != nil { - return nil, metadata, err - } - } - - for _, fn := range options.APIOptions { - if err := fn(stack); err != nil { - return nil, metadata, err - } - } - - ctx, err = withOperationMetrics(ctx, options.MeterProvider) - if err != nil { - return nil, metadata, err - } - - tracer := operationTracer(options.TracerProvider) - spanName := fmt.Sprintf("%s.%s", ServiceID, opID) - - ctx = tracing.WithOperationTracer(ctx, tracer) - - ctx, span := tracer.StartSpan(ctx, spanName, func(o *tracing.SpanOptions) { - o.Kind = tracing.SpanKindClient - o.Properties.Set("rpc.system", "aws-api") - o.Properties.Set("rpc.method", opID) - o.Properties.Set("rpc.service", ServiceID) - }) - endTimer := startMetricTimer(ctx, "client.call.duration") - defer endTimer() - defer span.End() - - handler := smithyhttp.NewClientHandlerWithOptions(options.HTTPClient, func(o *smithyhttp.ClientHandler) { - o.Meter = options.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sso") - }) - decorated := middleware.DecorateHandler(handler, stack) - result, metadata, err = decorated.Handle(ctx, params) - if err != nil { - span.SetProperty("exception.type", fmt.Sprintf("%T", err)) - span.SetProperty("exception.message", err.Error()) - - var aerr smithy.APIError - if errors.As(err, &aerr) { - span.SetProperty("api.error_code", aerr.ErrorCode()) - span.SetProperty("api.error_message", aerr.ErrorMessage()) - span.SetProperty("api.error_fault", aerr.ErrorFault().String()) - } - - err = &smithy.OperationError{ - ServiceID: ServiceID, - OperationName: opID, - Err: err, - } - } - - span.SetProperty("error", err != nil) - if err == nil { - span.SetStatus(tracing.SpanStatusOK) - } else { - span.SetStatus(tracing.SpanStatusError) - } - - return result, metadata, err -} - -type operationInputKey struct{} - -func setOperationInput(ctx context.Context, input interface{}) context.Context { - return middleware.WithStackValue(ctx, operationInputKey{}, input) -} - -func getOperationInput(ctx context.Context) interface{} { - return middleware.GetStackValue(ctx, operationInputKey{}) -} - -type setOperationInputMiddleware struct { -} - -func (*setOperationInputMiddleware) ID() string { - return "setOperationInput" -} - -func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - ctx = setOperationInput(ctx, in.Parameters) - return next.HandleSerialize(ctx, in) -} - -func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error { - if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil { - return fmt.Errorf("add ResolveAuthScheme: %w", err) - } - if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil { - return fmt.Errorf("add GetIdentity: %v", err) - } - if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil { - return fmt.Errorf("add ResolveEndpointV2: %v", err) - } - if err := stack.Finalize.Insert(&signRequestMiddleware{options: options}, "ResolveEndpointV2", middleware.After); err != nil { - return fmt.Errorf("add Signing: %w", err) - } - return nil -} -func resolveAuthSchemeResolver(options *Options) { - if options.AuthSchemeResolver == nil { - options.AuthSchemeResolver = &defaultAuthSchemeResolver{} - } -} - -func resolveAuthSchemes(options *Options) { - if options.AuthSchemes == nil { - options.AuthSchemes = []smithyhttp.AuthScheme{ - internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{ - Signer: options.HTTPSignerV4, - Logger: options.Logger, - LogSigning: options.ClientLogMode.IsSigning(), - }), - } - } -} - -type noSmithyDocumentSerde = smithydocument.NoSerde - -type legacyEndpointContextSetter struct { - LegacyResolver EndpointResolver -} - -func (*legacyEndpointContextSetter) ID() string { - return "legacyEndpointContextSetter" -} - -func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.LegacyResolver != nil { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) - } - - return next.HandleInitialize(ctx, in) - -} -func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { - return stack.Initialize.Add(&legacyEndpointContextSetter{ - LegacyResolver: o.EndpointResolver, - }, middleware.Before) -} - -func resolveDefaultLogger(o *Options) { - if o.Logger != nil { - return - } - o.Logger = logging.Nop{} -} - -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) -} - -func setResolvedDefaultsMode(o *Options) { - if len(o.resolvedDefaultsMode) > 0 { - return - } - - var mode aws.DefaultsMode - mode.SetFromString(string(o.DefaultsMode)) - - if mode == aws.DefaultsModeAuto { - mode = defaults.ResolveDefaultsModeAuto(o.Region, o.RuntimeEnvironment) - } - - o.resolvedDefaultsMode = mode -} - -// NewFromConfig returns a new client from the provided config. -func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { - opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, - } - resolveAWSRetryerProvider(cfg, &opts) - resolveAWSRetryMaxAttempts(cfg, &opts) - resolveAWSRetryMode(cfg, &opts) - resolveAWSEndpointResolver(cfg, &opts) - resolveUseDualStackEndpoint(cfg, &opts) - resolveUseFIPSEndpoint(cfg, &opts) - resolveBaseEndpoint(cfg, &opts) - return New(opts, optFns...) -} - -func resolveHTTPClient(o *Options) { - var buildable *awshttp.BuildableClient - - if o.HTTPClient != nil { - var ok bool - buildable, ok = o.HTTPClient.(*awshttp.BuildableClient) - if !ok { - return - } - } else { - buildable = awshttp.NewBuildableClient() - } - - modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) - if err == nil { - buildable = buildable.WithDialerOptions(func(dialer *net.Dialer) { - if dialerTimeout, ok := modeConfig.GetConnectTimeout(); ok { - dialer.Timeout = dialerTimeout - } - }) - - buildable = buildable.WithTransportOptions(func(transport *http.Transport) { - if tlsHandshakeTimeout, ok := modeConfig.GetTLSNegotiationTimeout(); ok { - transport.TLSHandshakeTimeout = tlsHandshakeTimeout - } - }) - } - - o.HTTPClient = buildable -} - -func resolveRetryer(o *Options) { - if o.Retryer != nil { - return - } - - if len(o.RetryMode) == 0 { - modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) - if err == nil { - o.RetryMode = modeConfig.RetryMode - } - } - if len(o.RetryMode) == 0 { - o.RetryMode = aws.RetryModeStandard - } - - var standardOptions []func(*retry.StandardOptions) - if v := o.RetryMaxAttempts; v != 0 { - standardOptions = append(standardOptions, func(so *retry.StandardOptions) { - so.MaxAttempts = v - }) - } - - switch o.RetryMode { - case aws.RetryModeAdaptive: - var adaptiveOptions []func(*retry.AdaptiveModeOptions) - if len(standardOptions) != 0 { - adaptiveOptions = append(adaptiveOptions, func(ao *retry.AdaptiveModeOptions) { - ao.StandardOptions = append(ao.StandardOptions, standardOptions...) - }) - } - o.Retryer = retry.NewAdaptiveMode(adaptiveOptions...) - - default: - o.Retryer = retry.NewStandard(standardOptions...) - } -} - -func resolveAWSRetryerProvider(cfg aws.Config, o *Options) { - if cfg.Retryer == nil { - return - } - o.Retryer = cfg.Retryer() -} - -func resolveAWSRetryMode(cfg aws.Config, o *Options) { - if len(cfg.RetryMode) == 0 { - return - } - o.RetryMode = cfg.RetryMode -} -func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) { - if cfg.RetryMaxAttempts == 0 { - return - } - o.RetryMaxAttempts = cfg.RetryMaxAttempts -} - -func finalizeRetryMaxAttempts(o *Options) { - if o.RetryMaxAttempts == 0 { - return - } - - o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) -} - -func finalizeOperationRetryMaxAttempts(o *Options, client Client) { - if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts { - return - } - - o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) -} - -func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { - if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { - return - } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) -} - -func addClientUserAgent(stack *middleware.Stack, options Options) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - ua.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "sso", goModuleVersion) - if len(options.AppID) > 0 { - ua.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID) - } - - return nil -} - -func getOrAddRequestUserAgent(stack *middleware.Stack) (*awsmiddleware.RequestUserAgent, error) { - id := (*awsmiddleware.RequestUserAgent)(nil).ID() - mw, ok := stack.Build.Get(id) - if !ok { - mw = awsmiddleware.NewRequestUserAgent() - if err := stack.Build.Add(mw, middleware.After); err != nil { - return nil, err - } - } - - ua, ok := mw.(*awsmiddleware.RequestUserAgent) - if !ok { - return nil, fmt.Errorf("%T for %s middleware did not match expected type", mw, id) - } - - return ua, nil -} - -type HTTPSignerV4 interface { - SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error -} - -func resolveHTTPSignerV4(o *Options) { - if o.HTTPSignerV4 != nil { - return - } - o.HTTPSignerV4 = newDefaultV4Signer(*o) -} - -func newDefaultV4Signer(o Options) *v4.Signer { - return v4.NewSigner(func(so *v4.SignerOptions) { - so.Logger = o.Logger - so.LogSigning = o.ClientLogMode.IsSigning() - }) -} - -func addClientRequestID(stack *middleware.Stack) error { - return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) -} - -func addComputeContentLength(stack *middleware.Stack) error { - return stack.Build.Add(&smithyhttp.ComputeContentLength{}, middleware.After) -} - -func addRawResponseToMetadata(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) -} - -func addRecordResponseTiming(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) -} - -func addSpanRetryLoop(stack *middleware.Stack, options Options) error { - return stack.Finalize.Insert(&spanRetryLoop{options: options}, "Retry", middleware.Before) -} - -type spanRetryLoop struct { - options Options -} - -func (*spanRetryLoop) ID() string { - return "spanRetryLoop" -} - -func (m *spanRetryLoop) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - middleware.FinalizeOutput, middleware.Metadata, error, -) { - tracer := operationTracer(m.options.TracerProvider) - ctx, span := tracer.StartSpan(ctx, "RetryLoop") - defer span.End() - - return next.HandleFinalize(ctx, in) -} -func addStreamingEventsPayload(stack *middleware.Stack) error { - return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before) -} - -func addUnsignedPayload(stack *middleware.Stack) error { - return stack.Finalize.Insert(&v4.UnsignedPayload{}, "ResolveEndpointV2", middleware.After) -} - -func addComputePayloadSHA256(stack *middleware.Stack) error { - return stack.Finalize.Insert(&v4.ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After) -} - -func addContentSHA256Header(stack *middleware.Stack) error { - return stack.Finalize.Insert(&v4.ContentSHA256Header{}, (*v4.ComputePayloadSHA256)(nil).ID(), middleware.After) -} - -func addIsWaiterUserAgent(o *Options) { - o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureWaiter) - return nil - }) -} - -func addIsPaginatorUserAgent(o *Options) { - o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeaturePaginator) - return nil - }) -} - -func addRetry(stack *middleware.Stack, o Options) error { - attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) { - m.LogAttempts = o.ClientLogMode.IsRetries() - m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sso") - }) - if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { - return err - } - if err := stack.Finalize.Insert(&retry.MetricsHeader{}, attempt.ID(), middleware.After); err != nil { - return err - } - return nil -} - -// resolves dual-stack endpoint configuration -func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error { - if len(cfg.ConfigSources) == 0 { - return nil - } - value, found, err := internalConfig.ResolveUseDualStackEndpoint(context.Background(), cfg.ConfigSources) - if err != nil { - return err - } - if found { - o.EndpointOptions.UseDualStackEndpoint = value - } - return nil -} - -// resolves FIPS endpoint configuration -func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error { - if len(cfg.ConfigSources) == 0 { - return nil - } - value, found, err := internalConfig.ResolveUseFIPSEndpoint(context.Background(), cfg.ConfigSources) - if err != nil { - return err - } - if found { - o.EndpointOptions.UseFIPSEndpoint = value - } - return nil -} - -func resolveAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) *string { - if mode == aws.AccountIDEndpointModeDisabled { - return nil - } - - if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); ok && ca.Credentials.AccountID != "" { - return aws.String(ca.Credentials.AccountID) - } - - return nil -} - -func addTimeOffsetBuild(stack *middleware.Stack, c *Client) error { - mw := internalmiddleware.AddTimeOffsetMiddleware{Offset: c.timeOffset} - if err := stack.Build.Add(&mw, middleware.After); err != nil { - return err - } - return stack.Deserialize.Insert(&mw, "RecordResponseTiming", middleware.Before) -} -func initializeTimeOffsetResolver(c *Client) { - c.timeOffset = new(atomic.Int64) -} - -func addUserAgentRetryMode(stack *middleware.Stack, options Options) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - switch options.Retryer.(type) { - case *retry.Standard: - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeStandard) - case *retry.AdaptiveMode: - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeAdaptive) - } - return nil -} - -func resolveTracerProvider(options *Options) { - if options.TracerProvider == nil { - options.TracerProvider = &tracing.NopTracerProvider{} - } -} - -func resolveMeterProvider(options *Options) { - if options.MeterProvider == nil { - options.MeterProvider = metrics.NopMeterProvider{} - } -} - -func addRecursionDetection(stack *middleware.Stack) error { - return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After) -} - -func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error { - return stack.Deserialize.Insert(&awsmiddleware.RequestIDRetriever{}, "OperationDeserializer", middleware.Before) - -} - -func addResponseErrorMiddleware(stack *middleware.Stack) error { - return stack.Deserialize.Insert(&awshttp.ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before) - -} - -func addRequestResponseLogging(stack *middleware.Stack, o Options) error { - return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{ - LogRequest: o.ClientLogMode.IsRequest(), - LogRequestWithBody: o.ClientLogMode.IsRequestWithBody(), - LogResponse: o.ClientLogMode.IsResponse(), - LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), - }, middleware.After) -} - -type disableHTTPSMiddleware struct { - DisableHTTPS bool -} - -func (*disableHTTPSMiddleware) ID() string { - return "disableHTTPS" -} - -func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { - req.URL.Scheme = "http" - } - - return next.HandleFinalize(ctx, in) -} - -func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { - return stack.Finalize.Insert(&disableHTTPSMiddleware{ - DisableHTTPS: o.EndpointOptions.DisableHTTPS, - }, "ResolveEndpointV2", middleware.After) -} - -type spanInitializeStart struct { -} - -func (*spanInitializeStart) ID() string { - return "spanInitializeStart" -} - -func (m *spanInitializeStart) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "Initialize") - - return next.HandleInitialize(ctx, in) -} - -type spanInitializeEnd struct { -} - -func (*spanInitializeEnd) ID() string { - return "spanInitializeEnd" -} - -func (m *spanInitializeEnd) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleInitialize(ctx, in) -} - -type spanBuildRequestStart struct { -} - -func (*spanBuildRequestStart) ID() string { - return "spanBuildRequestStart" -} - -func (m *spanBuildRequestStart) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - middleware.SerializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "BuildRequest") - - return next.HandleSerialize(ctx, in) -} - -type spanBuildRequestEnd struct { -} - -func (*spanBuildRequestEnd) ID() string { - return "spanBuildRequestEnd" -} - -func (m *spanBuildRequestEnd) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - middleware.BuildOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleBuild(ctx, in) -} - -func addSpanInitializeStart(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeStart{}, middleware.Before) -} - -func addSpanInitializeEnd(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeEnd{}, middleware.After) -} - -func addSpanBuildRequestStart(stack *middleware.Stack) error { - return stack.Serialize.Add(&spanBuildRequestStart{}, middleware.Before) -} - -func addSpanBuildRequestEnd(stack *middleware.Stack) error { - return stack.Build.Add(&spanBuildRequestEnd{}, middleware.After) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go deleted file mode 100644 index a656020..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go +++ /dev/null @@ -1,168 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sso/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns the STS short-term credentials for a given role name that is assigned -// to the user. -func (c *Client) GetRoleCredentials(ctx context.Context, params *GetRoleCredentialsInput, optFns ...func(*Options)) (*GetRoleCredentialsOutput, error) { - if params == nil { - params = &GetRoleCredentialsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetRoleCredentials", params, optFns, c.addOperationGetRoleCredentialsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetRoleCredentialsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetRoleCredentialsInput struct { - - // The token issued by the CreateToken API call. For more information, see [CreateToken] in the - // IAM Identity Center OIDC API Reference Guide. - // - // [CreateToken]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html - // - // This member is required. - AccessToken *string - - // The identifier for the AWS account that is assigned to the user. - // - // This member is required. - AccountId *string - - // The friendly name of the role that is assigned to the user. - // - // This member is required. - RoleName *string - - noSmithyDocumentSerde -} - -type GetRoleCredentialsOutput struct { - - // The credentials for the role that is assigned to the user. - RoleCredentials *types.RoleCredentials - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsRestjson1_serializeOpGetRoleCredentials{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsRestjson1_deserializeOpGetRoleCredentials{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetRoleCredentials"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addOpGetRoleCredentialsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRoleCredentials(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { - return err - } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetRoleCredentials(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetRoleCredentials", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go deleted file mode 100644 index 315526e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go +++ /dev/null @@ -1,266 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sso/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists all roles that are assigned to the user for a given AWS account. -func (c *Client) ListAccountRoles(ctx context.Context, params *ListAccountRolesInput, optFns ...func(*Options)) (*ListAccountRolesOutput, error) { - if params == nil { - params = &ListAccountRolesInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListAccountRoles", params, optFns, c.addOperationListAccountRolesMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListAccountRolesOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListAccountRolesInput struct { - - // The token issued by the CreateToken API call. For more information, see [CreateToken] in the - // IAM Identity Center OIDC API Reference Guide. - // - // [CreateToken]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html - // - // This member is required. - AccessToken *string - - // The identifier for the AWS account that is assigned to the user. - // - // This member is required. - AccountId *string - - // The number of items that clients can request per page. - MaxResults *int32 - - // The page token from the previous response output when you request subsequent - // pages. - NextToken *string - - noSmithyDocumentSerde -} - -type ListAccountRolesOutput struct { - - // The page token client that is used to retrieve the list of accounts. - NextToken *string - - // A paginated response with the list of roles and the next token if more results - // are available. - RoleList []types.RoleInfo - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsRestjson1_serializeOpListAccountRoles{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsRestjson1_deserializeOpListAccountRoles{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListAccountRoles"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addOpListAccountRolesValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListAccountRoles(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { - return err - } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { - return err - } - return nil -} - -// ListAccountRolesPaginatorOptions is the paginator options for ListAccountRoles -type ListAccountRolesPaginatorOptions struct { - // The number of items that clients can request per page. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListAccountRolesPaginator is a paginator for ListAccountRoles -type ListAccountRolesPaginator struct { - options ListAccountRolesPaginatorOptions - client ListAccountRolesAPIClient - params *ListAccountRolesInput - nextToken *string - firstPage bool -} - -// NewListAccountRolesPaginator returns a new ListAccountRolesPaginator -func NewListAccountRolesPaginator(client ListAccountRolesAPIClient, params *ListAccountRolesInput, optFns ...func(*ListAccountRolesPaginatorOptions)) *ListAccountRolesPaginator { - if params == nil { - params = &ListAccountRolesInput{} - } - - options := ListAccountRolesPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListAccountRolesPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListAccountRolesPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListAccountRoles page. -func (p *ListAccountRolesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListAccountRolesOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - optFns = append([]func(*Options){ - addIsPaginatorUserAgent, - }, optFns...) - result, err := p.client.ListAccountRoles(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -// ListAccountRolesAPIClient is a client that implements the ListAccountRoles -// operation. -type ListAccountRolesAPIClient interface { - ListAccountRoles(context.Context, *ListAccountRolesInput, ...func(*Options)) (*ListAccountRolesOutput, error) -} - -var _ ListAccountRolesAPIClient = (*Client)(nil) - -func newServiceMetadataMiddleware_opListAccountRoles(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListAccountRoles", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go deleted file mode 100644 index d867b78..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go +++ /dev/null @@ -1,264 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sso/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Lists all AWS accounts assigned to the user. These AWS accounts are assigned by -// the administrator of the account. For more information, see [Assign User Access]in the IAM Identity -// Center User Guide. This operation returns a paginated response. -// -// [Assign User Access]: https://docs.aws.amazon.com/singlesignon/latest/userguide/useraccess.html#assignusers -func (c *Client) ListAccounts(ctx context.Context, params *ListAccountsInput, optFns ...func(*Options)) (*ListAccountsOutput, error) { - if params == nil { - params = &ListAccountsInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "ListAccounts", params, optFns, c.addOperationListAccountsMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*ListAccountsOutput) - out.ResultMetadata = metadata - return out, nil -} - -type ListAccountsInput struct { - - // The token issued by the CreateToken API call. For more information, see [CreateToken] in the - // IAM Identity Center OIDC API Reference Guide. - // - // [CreateToken]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html - // - // This member is required. - AccessToken *string - - // This is the number of items clients can request per page. - MaxResults *int32 - - // (Optional) When requesting subsequent pages, this is the page token from the - // previous response output. - NextToken *string - - noSmithyDocumentSerde -} - -type ListAccountsOutput struct { - - // A paginated response with the list of account information and the next token if - // more results are available. - AccountList []types.AccountInfo - - // The page token client that is used to retrieve the list of accounts. - NextToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsRestjson1_serializeOpListAccounts{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsRestjson1_deserializeOpListAccounts{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "ListAccounts"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addOpListAccountsValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListAccounts(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { - return err - } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { - return err - } - return nil -} - -// ListAccountsPaginatorOptions is the paginator options for ListAccounts -type ListAccountsPaginatorOptions struct { - // This is the number of items clients can request per page. - Limit int32 - - // Set to true if pagination should stop if the service returns a pagination token - // that matches the most recent token provided to the service. - StopOnDuplicateToken bool -} - -// ListAccountsPaginator is a paginator for ListAccounts -type ListAccountsPaginator struct { - options ListAccountsPaginatorOptions - client ListAccountsAPIClient - params *ListAccountsInput - nextToken *string - firstPage bool -} - -// NewListAccountsPaginator returns a new ListAccountsPaginator -func NewListAccountsPaginator(client ListAccountsAPIClient, params *ListAccountsInput, optFns ...func(*ListAccountsPaginatorOptions)) *ListAccountsPaginator { - if params == nil { - params = &ListAccountsInput{} - } - - options := ListAccountsPaginatorOptions{} - if params.MaxResults != nil { - options.Limit = *params.MaxResults - } - - for _, fn := range optFns { - fn(&options) - } - - return &ListAccountsPaginator{ - options: options, - client: client, - params: params, - firstPage: true, - nextToken: params.NextToken, - } -} - -// HasMorePages returns a boolean indicating whether more pages are available -func (p *ListAccountsPaginator) HasMorePages() bool { - return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0) -} - -// NextPage retrieves the next ListAccounts page. -func (p *ListAccountsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*ListAccountsOutput, error) { - if !p.HasMorePages() { - return nil, fmt.Errorf("no more pages available") - } - - params := *p.params - params.NextToken = p.nextToken - - var limit *int32 - if p.options.Limit > 0 { - limit = &p.options.Limit - } - params.MaxResults = limit - - optFns = append([]func(*Options){ - addIsPaginatorUserAgent, - }, optFns...) - result, err := p.client.ListAccounts(ctx, ¶ms, optFns...) - if err != nil { - return nil, err - } - p.firstPage = false - - prevToken := p.nextToken - p.nextToken = result.NextToken - - if p.options.StopOnDuplicateToken && - prevToken != nil && - p.nextToken != nil && - *prevToken == *p.nextToken { - p.nextToken = nil - } - - return result, nil -} - -// ListAccountsAPIClient is a client that implements the ListAccounts operation. -type ListAccountsAPIClient interface { - ListAccounts(context.Context, *ListAccountsInput, ...func(*Options)) (*ListAccountsOutput, error) -} - -var _ ListAccountsAPIClient = (*Client)(nil) - -func newServiceMetadataMiddleware_opListAccounts(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "ListAccounts", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go deleted file mode 100644 index 434b430..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go +++ /dev/null @@ -1,167 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Removes the locally stored SSO tokens from the client-side cache and sends an -// API call to the IAM Identity Center service to invalidate the corresponding -// server-side IAM Identity Center sign in session. -// -// If a user uses IAM Identity Center to access the AWS CLI, the user’s IAM -// Identity Center sign in session is used to obtain an IAM session, as specified -// in the corresponding IAM Identity Center permission set. More specifically, IAM -// Identity Center assumes an IAM role in the target account on behalf of the user, -// and the corresponding temporary AWS credentials are returned to the client. -// -// After user logout, any existing IAM role sessions that were created by using -// IAM Identity Center permission sets continue based on the duration configured in -// the permission set. For more information, see [User authentications]in the IAM Identity Center User -// Guide. -// -// [User authentications]: https://docs.aws.amazon.com/singlesignon/latest/userguide/authconcept.html -func (c *Client) Logout(ctx context.Context, params *LogoutInput, optFns ...func(*Options)) (*LogoutOutput, error) { - if params == nil { - params = &LogoutInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "Logout", params, optFns, c.addOperationLogoutMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*LogoutOutput) - out.ResultMetadata = metadata - return out, nil -} - -type LogoutInput struct { - - // The token issued by the CreateToken API call. For more information, see [CreateToken] in the - // IAM Identity Center OIDC API Reference Guide. - // - // [CreateToken]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/API_CreateToken.html - // - // This member is required. - AccessToken *string - - noSmithyDocumentSerde -} - -type LogoutOutput struct { - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsRestjson1_serializeOpLogout{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsRestjson1_deserializeOpLogout{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "Logout"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addOpLogoutValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opLogout(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { - return err - } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opLogout(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "Logout", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/auth.go deleted file mode 100644 index 366963b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/auth.go +++ /dev/null @@ -1,337 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - smithy "github.com/aws/smithy-go" - smithyauth "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) { - params.Region = options.Region -} - -type setLegacyContextSigningOptionsMiddleware struct { -} - -func (*setLegacyContextSigningOptionsMiddleware) ID() string { - return "setLegacyContextSigningOptions" -} - -func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - rscheme := getResolvedAuthScheme(ctx) - schemeID := rscheme.Scheme.SchemeID() - - if sn := awsmiddleware.GetSigningName(ctx); sn != "" { - if schemeID == "aws.auth#sigv4" { - smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn) - } else if schemeID == "aws.auth#sigv4a" { - smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn) - } - } - - if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" { - if schemeID == "aws.auth#sigv4" { - smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr) - } else if schemeID == "aws.auth#sigv4a" { - smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr}) - } - } - - return next.HandleFinalize(ctx, in) -} - -func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error { - return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before) -} - -type withAnonymous struct { - resolver AuthSchemeResolver -} - -var _ AuthSchemeResolver = (*withAnonymous)(nil) - -func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { - opts, err := v.resolver.ResolveAuthSchemes(ctx, params) - if err != nil { - return nil, err - } - - opts = append(opts, &smithyauth.Option{ - SchemeID: smithyauth.SchemeIDAnonymous, - }) - return opts, nil -} - -func wrapWithAnonymousAuth(options *Options) { - if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok { - return - } - - options.AuthSchemeResolver = &withAnonymous{ - resolver: options.AuthSchemeResolver, - } -} - -// AuthResolverParameters contains the set of inputs necessary for auth scheme -// resolution. -type AuthResolverParameters struct { - // The name of the operation being invoked. - Operation string - - // The region in which the operation is being invoked. - Region string -} - -func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters { - params := &AuthResolverParameters{ - Operation: operation, - } - - bindAuthParamsRegion(ctx, params, input, options) - - return params -} - -// AuthSchemeResolver returns a set of possible authentication options for an -// operation. -type AuthSchemeResolver interface { - ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error) -} - -type defaultAuthSchemeResolver struct{} - -var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil) - -func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { - if overrides, ok := operationAuthOptions[params.Operation]; ok { - return overrides(params), nil - } - return serviceAuthOptions(params), nil -} - -var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{ - "GetRoleCredentials": func(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - {SchemeID: smithyauth.SchemeIDAnonymous}, - } - }, - - "ListAccountRoles": func(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - {SchemeID: smithyauth.SchemeIDAnonymous}, - } - }, - - "ListAccounts": func(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - {SchemeID: smithyauth.SchemeIDAnonymous}, - } - }, - - "Logout": func(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - {SchemeID: smithyauth.SchemeIDAnonymous}, - } - }, -} - -func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - { - SchemeID: smithyauth.SchemeIDSigV4, - SignerProperties: func() smithy.Properties { - var props smithy.Properties - smithyhttp.SetSigV4SigningName(&props, "awsssoportal") - smithyhttp.SetSigV4SigningRegion(&props, params.Region) - return props - }(), - }, - } -} - -type resolveAuthSchemeMiddleware struct { - operation string - options Options -} - -func (*resolveAuthSchemeMiddleware) ID() string { - return "ResolveAuthScheme" -} - -func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "ResolveAuthScheme") - defer span.End() - - params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) - options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) - if err != nil { - return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) - } - - scheme, ok := m.selectScheme(options) - if !ok { - return out, metadata, fmt.Errorf("could not select an auth scheme") - } - - ctx = setResolvedAuthScheme(ctx, scheme) - - span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID()) - span.End() - return next.HandleFinalize(ctx, in) -} - -func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - for _, option := range options { - if option.SchemeID == smithyauth.SchemeIDAnonymous { - return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true - } - - for _, scheme := range m.options.AuthSchemes { - if scheme.SchemeID() != option.SchemeID { - continue - } - - if scheme.IdentityResolver(m.options) != nil { - return newResolvedAuthScheme(scheme, option), true - } - } - } - - return nil, false -} - -type resolvedAuthSchemeKey struct{} - -type resolvedAuthScheme struct { - Scheme smithyhttp.AuthScheme - IdentityProperties smithy.Properties - SignerProperties smithy.Properties -} - -func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme { - return &resolvedAuthScheme{ - Scheme: scheme, - IdentityProperties: option.IdentityProperties, - SignerProperties: option.SignerProperties, - } -} - -func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context { - return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme) -} - -func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme { - v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme) - return v -} - -type getIdentityMiddleware struct { - options Options -} - -func (*getIdentityMiddleware) ID() string { - return "GetIdentity" -} - -func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - innerCtx, span := tracing.StartSpan(ctx, "GetIdentity") - defer span.End() - - rscheme := getResolvedAuthScheme(innerCtx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - resolver := rscheme.Scheme.IdentityResolver(m.options) - if resolver == nil { - return out, metadata, fmt.Errorf("no identity resolver") - } - - identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration", - func() (smithyauth.Identity, error) { - return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties) - }, - func(o *metrics.RecordMetricOptions) { - o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) - }) - if err != nil { - return out, metadata, fmt.Errorf("get identity: %w", err) - } - - ctx = setIdentity(ctx, identity) - - span.End() - return next.HandleFinalize(ctx, in) -} - -type identityKey struct{} - -func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context { - return middleware.WithStackValue(ctx, identityKey{}, identity) -} - -func getIdentity(ctx context.Context) smithyauth.Identity { - v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity) - return v -} - -type signRequestMiddleware struct { - options Options -} - -func (*signRequestMiddleware) ID() string { - return "Signing" -} - -func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "SignRequest") - defer span.End() - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request) - } - - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - identity := getIdentity(ctx) - if identity == nil { - return out, metadata, fmt.Errorf("no identity") - } - - signer := rscheme.Scheme.Signer() - if signer == nil { - return out, metadata, fmt.Errorf("no signer") - } - - _, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) { - return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties) - }, func(o *metrics.RecordMetricOptions) { - o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) - }) - if err != nil { - return out, metadata, fmt.Errorf("sign request: %w", err) - } - - span.End() - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go deleted file mode 100644 index ec23c36..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go +++ /dev/null @@ -1,1182 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws/protocol/restjson" - "github.com/aws/aws-sdk-go-v2/service/sso/types" - smithy "github.com/aws/smithy-go" - smithyio "github.com/aws/smithy-go/io" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/ptr" - smithytime "github.com/aws/smithy-go/time" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "io" - "io/ioutil" - "strings" - "time" -) - -func deserializeS3Expires(v string) (*time.Time, error) { - t, err := smithytime.ParseHTTPDate(v) - if err != nil { - return nil, nil - } - return &t, nil -} - -type awsRestjson1_deserializeOpGetRoleCredentials struct { -} - -func (*awsRestjson1_deserializeOpGetRoleCredentials) ID() string { - return "OperationDeserializer" -} - -func (m *awsRestjson1_deserializeOpGetRoleCredentials) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorGetRoleCredentials(response, &metadata) - } - output := &GetRoleCredentialsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsRestjson1_deserializeOpDocumentGetRoleCredentialsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - span.End() - return out, metadata, err -} - -func awsRestjson1_deserializeOpErrorGetRoleCredentials(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InvalidRequestException", errorCode): - return awsRestjson1_deserializeErrorInvalidRequestException(response, errorBody) - - case strings.EqualFold("ResourceNotFoundException", errorCode): - return awsRestjson1_deserializeErrorResourceNotFoundException(response, errorBody) - - case strings.EqualFold("TooManyRequestsException", errorCode): - return awsRestjson1_deserializeErrorTooManyRequestsException(response, errorBody) - - case strings.EqualFold("UnauthorizedException", errorCode): - return awsRestjson1_deserializeErrorUnauthorizedException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsRestjson1_deserializeOpDocumentGetRoleCredentialsOutput(v **GetRoleCredentialsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *GetRoleCredentialsOutput - if *v == nil { - sv = &GetRoleCredentialsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "roleCredentials": - if err := awsRestjson1_deserializeDocumentRoleCredentials(&sv.RoleCredentials, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -type awsRestjson1_deserializeOpListAccountRoles struct { -} - -func (*awsRestjson1_deserializeOpListAccountRoles) ID() string { - return "OperationDeserializer" -} - -func (m *awsRestjson1_deserializeOpListAccountRoles) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorListAccountRoles(response, &metadata) - } - output := &ListAccountRolesOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsRestjson1_deserializeOpDocumentListAccountRolesOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - span.End() - return out, metadata, err -} - -func awsRestjson1_deserializeOpErrorListAccountRoles(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InvalidRequestException", errorCode): - return awsRestjson1_deserializeErrorInvalidRequestException(response, errorBody) - - case strings.EqualFold("ResourceNotFoundException", errorCode): - return awsRestjson1_deserializeErrorResourceNotFoundException(response, errorBody) - - case strings.EqualFold("TooManyRequestsException", errorCode): - return awsRestjson1_deserializeErrorTooManyRequestsException(response, errorBody) - - case strings.EqualFold("UnauthorizedException", errorCode): - return awsRestjson1_deserializeErrorUnauthorizedException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsRestjson1_deserializeOpDocumentListAccountRolesOutput(v **ListAccountRolesOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListAccountRolesOutput - if *v == nil { - sv = &ListAccountRolesOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "nextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextTokenType to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - case "roleList": - if err := awsRestjson1_deserializeDocumentRoleListType(&sv.RoleList, value); err != nil { - return err - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -type awsRestjson1_deserializeOpListAccounts struct { -} - -func (*awsRestjson1_deserializeOpListAccounts) ID() string { - return "OperationDeserializer" -} - -func (m *awsRestjson1_deserializeOpListAccounts) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorListAccounts(response, &metadata) - } - output := &ListAccountsOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsRestjson1_deserializeOpDocumentListAccountsOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - span.End() - return out, metadata, err -} - -func awsRestjson1_deserializeOpErrorListAccounts(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InvalidRequestException", errorCode): - return awsRestjson1_deserializeErrorInvalidRequestException(response, errorBody) - - case strings.EqualFold("ResourceNotFoundException", errorCode): - return awsRestjson1_deserializeErrorResourceNotFoundException(response, errorBody) - - case strings.EqualFold("TooManyRequestsException", errorCode): - return awsRestjson1_deserializeErrorTooManyRequestsException(response, errorBody) - - case strings.EqualFold("UnauthorizedException", errorCode): - return awsRestjson1_deserializeErrorUnauthorizedException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsRestjson1_deserializeOpDocumentListAccountsOutput(v **ListAccountsOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *ListAccountsOutput - if *v == nil { - sv = &ListAccountsOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "accountList": - if err := awsRestjson1_deserializeDocumentAccountListType(&sv.AccountList, value); err != nil { - return err - } - - case "nextToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected NextTokenType to be of type string, got %T instead", value) - } - sv.NextToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -type awsRestjson1_deserializeOpLogout struct { -} - -func (*awsRestjson1_deserializeOpLogout) ID() string { - return "OperationDeserializer" -} - -func (m *awsRestjson1_deserializeOpLogout) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorLogout(response, &metadata) - } - output := &LogoutOutput{} - out.Result = output - - if _, err = io.Copy(ioutil.Discard, response.Body); err != nil { - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to discard response body, %w", err), - } - } - - span.End() - return out, metadata, err -} - -func awsRestjson1_deserializeOpErrorLogout(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InvalidRequestException", errorCode): - return awsRestjson1_deserializeErrorInvalidRequestException(response, errorBody) - - case strings.EqualFold("TooManyRequestsException", errorCode): - return awsRestjson1_deserializeErrorTooManyRequestsException(response, errorBody) - - case strings.EqualFold("UnauthorizedException", errorCode): - return awsRestjson1_deserializeErrorUnauthorizedException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsRestjson1_deserializeErrorInvalidRequestException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidRequestException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentInvalidRequestException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorResourceNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.ResourceNotFoundException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentResourceNotFoundException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorTooManyRequestsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.TooManyRequestsException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentTooManyRequestsException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorUnauthorizedException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.UnauthorizedException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentUnauthorizedException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeDocumentAccountInfo(v **types.AccountInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AccountInfo - if *v == nil { - sv = &types.AccountInfo{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "accountId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AccountIdType to be of type string, got %T instead", value) - } - sv.AccountId = ptr.String(jtv) - } - - case "accountName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AccountNameType to be of type string, got %T instead", value) - } - sv.AccountName = ptr.String(jtv) - } - - case "emailAddress": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected EmailAddressType to be of type string, got %T instead", value) - } - sv.EmailAddress = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentAccountListType(v *[]types.AccountInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.AccountInfo - if *v == nil { - cv = []types.AccountInfo{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.AccountInfo - destAddr := &col - if err := awsRestjson1_deserializeDocumentAccountInfo(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsRestjson1_deserializeDocumentInvalidRequestException(v **types.InvalidRequestException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidRequestException - if *v == nil { - sv = &types.InvalidRequestException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message", "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentResourceNotFoundException(v **types.ResourceNotFoundException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ResourceNotFoundException - if *v == nil { - sv = &types.ResourceNotFoundException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message", "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentRoleCredentials(v **types.RoleCredentials, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.RoleCredentials - if *v == nil { - sv = &types.RoleCredentials{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "accessKeyId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AccessKeyType to be of type string, got %T instead", value) - } - sv.AccessKeyId = ptr.String(jtv) - } - - case "expiration": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ExpirationTimestampType to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Expiration = i64 - } - - case "secretAccessKey": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SecretAccessKeyType to be of type string, got %T instead", value) - } - sv.SecretAccessKey = ptr.String(jtv) - } - - case "sessionToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected SessionTokenType to be of type string, got %T instead", value) - } - sv.SessionToken = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentRoleInfo(v **types.RoleInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.RoleInfo - if *v == nil { - sv = &types.RoleInfo{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "accountId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AccountIdType to be of type string, got %T instead", value) - } - sv.AccountId = ptr.String(jtv) - } - - case "roleName": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected RoleNameType to be of type string, got %T instead", value) - } - sv.RoleName = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentRoleListType(v *[]types.RoleInfo, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []types.RoleInfo - if *v == nil { - cv = []types.RoleInfo{} - } else { - cv = *v - } - - for _, value := range shape { - var col types.RoleInfo - destAddr := &col - if err := awsRestjson1_deserializeDocumentRoleInfo(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsRestjson1_deserializeDocumentTooManyRequestsException(v **types.TooManyRequestsException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.TooManyRequestsException - if *v == nil { - sv = &types.TooManyRequestsException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message", "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentUnauthorizedException(v **types.UnauthorizedException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnauthorizedException - if *v == nil { - sv = &types.UnauthorizedException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "message", "Message": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Message = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/doc.go deleted file mode 100644 index 7f6e429..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/doc.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -// Package sso provides the API client, operations, and parameter types for AWS -// Single Sign-On. -// -// AWS IAM Identity Center (successor to AWS Single Sign-On) Portal is a web -// service that makes it easy for you to assign user access to IAM Identity Center -// resources such as the AWS access portal. Users can get AWS account applications -// and roles assigned to them and get federated into the application. -// -// Although AWS Single Sign-On was renamed, the sso and identitystore API -// namespaces will continue to retain their original name for backward -// compatibility purposes. For more information, see [IAM Identity Center rename]. -// -// This reference guide describes the IAM Identity Center Portal operations that -// you can call programatically and includes detailed information on data types and -// errors. -// -// AWS provides SDKs that consist of libraries and sample code for various -// programming languages and platforms, such as Java, Ruby, .Net, iOS, or Android. -// The SDKs provide a convenient way to create programmatic access to IAM Identity -// Center and other AWS services. For more information about the AWS SDKs, -// including how to download and install them, see [Tools for Amazon Web Services]. -// -// [Tools for Amazon Web Services]: http://aws.amazon.com/tools/ -// [IAM Identity Center rename]: https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html#renamed -package sso diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/endpoints.go deleted file mode 100644 index 53c6bc7..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/endpoints.go +++ /dev/null @@ -1,556 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "errors" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" - "github.com/aws/aws-sdk-go-v2/internal/endpoints" - "github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn" - internalendpoints "github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints" - smithyauth "github.com/aws/smithy-go/auth" - smithyendpoints "github.com/aws/smithy-go/endpoints" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/ptr" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net/http" - "net/url" - "os" - "strings" -) - -// EndpointResolverOptions is the service endpoint resolver options -type EndpointResolverOptions = internalendpoints.Options - -// EndpointResolver interface for resolving service endpoints. -type EndpointResolver interface { - ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error) -} - -var _ EndpointResolver = &internalendpoints.Resolver{} - -// NewDefaultEndpointResolver constructs a new service endpoint resolver -func NewDefaultEndpointResolver() *internalendpoints.Resolver { - return internalendpoints.New() -} - -// EndpointResolverFunc is a helper utility that wraps a function so it satisfies -// the EndpointResolver interface. This is useful when you want to add additional -// endpoint resolving logic, or stub out specific endpoints with custom values. -type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error) - -func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - return fn(region, options) -} - -// EndpointResolverFromURL returns an EndpointResolver configured using the -// provided endpoint url. By default, the resolved endpoint resolver uses the -// client region as signing region, and the endpoint source is set to -// EndpointSourceCustom.You can provide functional options to configure endpoint -// values for the resolved endpoint. -func EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver { - e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom} - for _, fn := range optFns { - fn(&e) - } - - return EndpointResolverFunc( - func(region string, options EndpointResolverOptions) (aws.Endpoint, error) { - if len(e.SigningRegion) == 0 { - e.SigningRegion = region - } - return e, nil - }, - ) -} - -type ResolveEndpoint struct { - Resolver EndpointResolver - Options EndpointResolverOptions -} - -func (*ResolveEndpoint) ID() string { - return "ResolveEndpoint" -} - -func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { - return next.HandleSerialize(ctx, in) - } - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.Resolver == nil { - return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") - } - - eo := m.Options - eo.Logger = middleware.GetLogger(ctx) - - var endpoint aws.Endpoint - endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo) - if err != nil { - nf := (&aws.EndpointNotFoundError{}) - if errors.As(err, &nf) { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false) - return next.HandleSerialize(ctx, in) - } - return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) - } - - req.URL, err = url.Parse(endpoint.URL) - if err != nil { - return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err) - } - - if len(awsmiddleware.GetSigningName(ctx)) == 0 { - signingName := endpoint.SigningName - if len(signingName) == 0 { - signingName = "awsssoportal" - } - ctx = awsmiddleware.SetSigningName(ctx, signingName) - } - ctx = awsmiddleware.SetEndpointSource(ctx, endpoint.Source) - ctx = smithyhttp.SetHostnameImmutable(ctx, endpoint.HostnameImmutable) - ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion) - ctx = awsmiddleware.SetPartitionID(ctx, endpoint.PartitionID) - return next.HandleSerialize(ctx, in) -} -func addResolveEndpointMiddleware(stack *middleware.Stack, o Options) error { - return stack.Serialize.Insert(&ResolveEndpoint{ - Resolver: o.EndpointResolver, - Options: o.EndpointOptions, - }, "OperationSerializer", middleware.Before) -} - -func removeResolveEndpointMiddleware(stack *middleware.Stack) error { - _, err := stack.Serialize.Remove((&ResolveEndpoint{}).ID()) - return err -} - -type wrappedEndpointResolver struct { - awsResolver aws.EndpointResolverWithOptions -} - -func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - return w.awsResolver.ResolveEndpoint(ServiceID, region, options) -} - -type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) - -func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) { - return a(service, region) -} - -var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) - -// withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error, -// and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked -// via its middleware. -// -// If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated. -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver { - var resolver aws.EndpointResolverWithOptions - - if awsResolverWithOptions != nil { - resolver = awsResolverWithOptions - } else if awsResolver != nil { - resolver = awsEndpointResolverAdaptor(awsResolver.ResolveEndpoint) - } - - return &wrappedEndpointResolver{ - awsResolver: resolver, - } -} - -func finalizeClientEndpointResolverOptions(options *Options) { - options.EndpointOptions.LogDeprecated = options.ClientLogMode.IsDeprecatedUsage() - - if len(options.EndpointOptions.ResolvedRegion) == 0 { - const fipsInfix = "-fips-" - const fipsPrefix = "fips-" - const fipsSuffix = "-fips" - - if strings.Contains(options.Region, fipsInfix) || - strings.Contains(options.Region, fipsPrefix) || - strings.Contains(options.Region, fipsSuffix) { - options.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( - options.Region, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") - options.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled - } - } - -} - -func resolveEndpointResolverV2(options *Options) { - if options.EndpointResolverV2 == nil { - options.EndpointResolverV2 = NewDefaultEndpointResolverV2() - } -} - -func resolveBaseEndpoint(cfg aws.Config, o *Options) { - if cfg.BaseEndpoint != nil { - o.BaseEndpoint = cfg.BaseEndpoint - } - - _, g := os.LookupEnv("AWS_ENDPOINT_URL") - _, s := os.LookupEnv("AWS_ENDPOINT_URL_SSO") - - if g && !s { - return - } - - value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "SSO", cfg.ConfigSources) - if found && err == nil { - o.BaseEndpoint = &value - } -} - -func bindRegion(region string) *string { - if region == "" { - return nil - } - return aws.String(endpoints.MapFIPSRegion(region)) -} - -// EndpointParameters provides the parameters that influence how endpoints are -// resolved. -type EndpointParameters struct { - // The AWS region used to dispatch the request. - // - // Parameter is - // required. - // - // AWS::Region - Region *string - - // When true, use the dual-stack endpoint. If the configured endpoint does not - // support dual-stack, dispatching the request MAY return an error. - // - // Defaults to - // false if no value is provided. - // - // AWS::UseDualStack - UseDualStack *bool - - // When true, send this request to the FIPS-compliant regional endpoint. If the - // configured endpoint does not have a FIPS compliant endpoint, dispatching the - // request will return an error. - // - // Defaults to false if no value is - // provided. - // - // AWS::UseFIPS - UseFIPS *bool - - // Override the endpoint used to send this request - // - // Parameter is - // required. - // - // SDK::Endpoint - Endpoint *string -} - -// ValidateRequired validates required parameters are set. -func (p EndpointParameters) ValidateRequired() error { - if p.UseDualStack == nil { - return fmt.Errorf("parameter UseDualStack is required") - } - - if p.UseFIPS == nil { - return fmt.Errorf("parameter UseFIPS is required") - } - - return nil -} - -// WithDefaults returns a shallow copy of EndpointParameterswith default values -// applied to members where applicable. -func (p EndpointParameters) WithDefaults() EndpointParameters { - if p.UseDualStack == nil { - p.UseDualStack = ptr.Bool(false) - } - - if p.UseFIPS == nil { - p.UseFIPS = ptr.Bool(false) - } - return p -} - -type stringSlice []string - -func (s stringSlice) Get(i int) *string { - if i < 0 || i >= len(s) { - return nil - } - - v := s[i] - return &v -} - -// EndpointResolverV2 provides the interface for resolving service endpoints. -type EndpointResolverV2 interface { - // ResolveEndpoint attempts to resolve the endpoint with the provided options, - // returning the endpoint if found. Otherwise an error is returned. - ResolveEndpoint(ctx context.Context, params EndpointParameters) ( - smithyendpoints.Endpoint, error, - ) -} - -// resolver provides the implementation for resolving endpoints. -type resolver struct{} - -func NewDefaultEndpointResolverV2() EndpointResolverV2 { - return &resolver{} -} - -// ResolveEndpoint attempts to resolve the endpoint with the provided options, -// returning the endpoint if found. Otherwise an error is returned. -func (r *resolver) ResolveEndpoint( - ctx context.Context, params EndpointParameters, -) ( - endpoint smithyendpoints.Endpoint, err error, -) { - params = params.WithDefaults() - if err = params.ValidateRequired(); err != nil { - return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) - } - _UseDualStack := *params.UseDualStack - _UseFIPS := *params.UseFIPS - - if exprVal := params.Endpoint; exprVal != nil { - _Endpoint := *exprVal - _ = _Endpoint - if _UseFIPS == true { - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported") - } - if _UseDualStack == true { - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported") - } - uriString := _Endpoint - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - if exprVal := params.Region; exprVal != nil { - _Region := *exprVal - _ = _Region - if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { - _PartitionResult := *exprVal - _ = _PartitionResult - if _UseFIPS == true { - if _UseDualStack == true { - if true == _PartitionResult.SupportsFIPS { - if true == _PartitionResult.SupportsDualStack { - uriString := func() string { - var out strings.Builder - out.WriteString("https://portal.sso-fips.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DualStackDnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") - } - } - if _UseFIPS == true { - if true == _PartitionResult.SupportsFIPS { - if "aws-us-gov" == _PartitionResult.Name { - uriString := func() string { - var out strings.Builder - out.WriteString("https://portal.sso.") - out.WriteString(_Region) - out.WriteString(".amazonaws.com") - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - uriString := func() string { - var out strings.Builder - out.WriteString("https://portal.sso-fips.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS") - } - if _UseDualStack == true { - if true == _PartitionResult.SupportsDualStack { - uriString := func() string { - var out strings.Builder - out.WriteString("https://portal.sso.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DualStackDnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack") - } - uriString := func() string { - var out strings.Builder - out.WriteString("https://portal.sso.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region") -} - -type endpointParamsBinder interface { - bindEndpointParams(*EndpointParameters) -} - -func bindEndpointParams(ctx context.Context, input interface{}, options Options) *EndpointParameters { - params := &EndpointParameters{} - - params.Region = bindRegion(options.Region) - params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) - params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) - params.Endpoint = options.BaseEndpoint - - if b, ok := input.(endpointParamsBinder); ok { - b.bindEndpointParams(params) - } - - return params -} - -type resolveEndpointV2Middleware struct { - options Options -} - -func (*resolveEndpointV2Middleware) ID() string { - return "ResolveEndpointV2" -} - -func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "ResolveEndpoint") - defer span.End() - - if awsmiddleware.GetRequiresLegacyEndpoints(ctx) { - return next.HandleFinalize(ctx, in) - } - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.options.EndpointResolverV2 == nil { - return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") - } - - params := bindEndpointParams(ctx, getOperationInput(ctx), m.options) - endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration", - func() (smithyendpoints.Endpoint, error) { - return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) - }) - if err != nil { - return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) - } - - span.SetProperty("client.call.resolved_endpoint", endpt.URI.String()) - - if endpt.URI.RawPath == "" && req.URL.RawPath != "" { - endpt.URI.RawPath = endpt.URI.Path - } - req.URL.Scheme = endpt.URI.Scheme - req.URL.Host = endpt.URI.Host - req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path) - req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath) - for k := range endpt.Headers { - req.Header.Set(k, endpt.Headers.Get(k)) - } - - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - opts, _ := smithyauth.GetAuthOptions(&endpt.Properties) - for _, o := range opts { - rscheme.SignerProperties.SetAll(&o.SignerProperties) - } - - span.End() - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json deleted file mode 100644 index 936253d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "dependencies": { - "github.com/aws/aws-sdk-go-v2": "v1.4.0", - "github.com/aws/aws-sdk-go-v2/internal/configsources": "v0.0.0-00010101000000-000000000000", - "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2": "v2.0.0-00010101000000-000000000000", - "github.com/aws/smithy-go": "v1.4.0" - }, - "files": [ - "api_client.go", - "api_client_test.go", - "api_op_GetRoleCredentials.go", - "api_op_ListAccountRoles.go", - "api_op_ListAccounts.go", - "api_op_Logout.go", - "auth.go", - "deserializers.go", - "doc.go", - "endpoints.go", - "endpoints_config_test.go", - "endpoints_test.go", - "generated.json", - "internal/endpoints/endpoints.go", - "internal/endpoints/endpoints_test.go", - "options.go", - "protocol_test.go", - "serializers.go", - "snapshot_test.go", - "types/errors.go", - "types/types.go", - "validators.go" - ], - "go": "1.15", - "module": "github.com/aws/aws-sdk-go-v2/service/sso", - "unstable": false -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go deleted file mode 100644 index 43c6740..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package sso - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.24.14" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go deleted file mode 100644 index 081867b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go +++ /dev/null @@ -1,566 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package endpoints - -import ( - "github.com/aws/aws-sdk-go-v2/aws" - endpoints "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2" - "github.com/aws/smithy-go/logging" - "regexp" -) - -// Options is the endpoint resolver configuration options -type Options struct { - // Logger is a logging implementation that log events should be sent to. - Logger logging.Logger - - // LogDeprecated indicates that deprecated endpoints should be logged to the - // provided logger. - LogDeprecated bool - - // ResolvedRegion is used to override the region to be resolved, rather then the - // using the value passed to the ResolveEndpoint method. This value is used by the - // SDK to translate regions like fips-us-east-1 or us-east-1-fips to an alternative - // name. You must not set this value directly in your application. - ResolvedRegion string - - // DisableHTTPS informs the resolver to return an endpoint that does not use the - // HTTPS scheme. - DisableHTTPS bool - - // UseDualStackEndpoint specifies the resolver must resolve a dual-stack endpoint. - UseDualStackEndpoint aws.DualStackEndpointState - - // UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint. - UseFIPSEndpoint aws.FIPSEndpointState -} - -func (o Options) GetResolvedRegion() string { - return o.ResolvedRegion -} - -func (o Options) GetDisableHTTPS() bool { - return o.DisableHTTPS -} - -func (o Options) GetUseDualStackEndpoint() aws.DualStackEndpointState { - return o.UseDualStackEndpoint -} - -func (o Options) GetUseFIPSEndpoint() aws.FIPSEndpointState { - return o.UseFIPSEndpoint -} - -func transformToSharedOptions(options Options) endpoints.Options { - return endpoints.Options{ - Logger: options.Logger, - LogDeprecated: options.LogDeprecated, - ResolvedRegion: options.ResolvedRegion, - DisableHTTPS: options.DisableHTTPS, - UseDualStackEndpoint: options.UseDualStackEndpoint, - UseFIPSEndpoint: options.UseFIPSEndpoint, - } -} - -// Resolver SSO endpoint resolver -type Resolver struct { - partitions endpoints.Partitions -} - -// ResolveEndpoint resolves the service endpoint for the given region and options -func (r *Resolver) ResolveEndpoint(region string, options Options) (endpoint aws.Endpoint, err error) { - if len(region) == 0 { - return endpoint, &aws.MissingRegionError{} - } - - opt := transformToSharedOptions(options) - return r.partitions.ResolveEndpoint(region, opt) -} - -// New returns a new Resolver -func New() *Resolver { - return &Resolver{ - partitions: defaultPartitions, - } -} - -var partitionRegexp = struct { - Aws *regexp.Regexp - AwsCn *regexp.Regexp - AwsIso *regexp.Regexp - AwsIsoB *regexp.Regexp - AwsIsoE *regexp.Regexp - AwsIsoF *regexp.Regexp - AwsUsGov *regexp.Regexp -}{ - - Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"), - AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), - AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), - AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), - AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), - AwsIsoF: regexp.MustCompile("^us\\-isof\\-\\w+\\-\\d+$"), - AwsUsGov: regexp.MustCompile("^us\\-gov\\-\\w+\\-\\d+$"), -} - -var defaultPartitions = endpoints.Partitions{ - { - ID: "aws", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "portal.sso.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "portal.sso-fips.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "portal.sso-fips.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "portal.sso.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.Aws, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "af-south-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.af-south-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "af-south-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-east-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-east-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-northeast-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-northeast-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-northeast-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-northeast-2", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-northeast-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-northeast-2", - }, - }, - endpoints.EndpointKey{ - Region: "ap-northeast-3", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-northeast-3.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-northeast-3", - }, - }, - endpoints.EndpointKey{ - Region: "ap-south-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-south-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-south-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-south-2", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-south-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-south-2", - }, - }, - endpoints.EndpointKey{ - Region: "ap-southeast-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-southeast-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-southeast-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-southeast-2", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-southeast-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-southeast-2", - }, - }, - endpoints.EndpointKey{ - Region: "ap-southeast-3", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-southeast-3.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-southeast-3", - }, - }, - endpoints.EndpointKey{ - Region: "ap-southeast-4", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ap-southeast-4.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-southeast-4", - }, - }, - endpoints.EndpointKey{ - Region: "ca-central-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ca-central-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ca-central-1", - }, - }, - endpoints.EndpointKey{ - Region: "ca-west-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.ca-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ca-west-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-central-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.eu-central-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-central-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-central-2", - }: endpoints.Endpoint{ - Hostname: "portal.sso.eu-central-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-central-2", - }, - }, - endpoints.EndpointKey{ - Region: "eu-north-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.eu-north-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-north-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-south-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.eu-south-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-south-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-south-2", - }: endpoints.Endpoint{ - Hostname: "portal.sso.eu-south-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-south-2", - }, - }, - endpoints.EndpointKey{ - Region: "eu-west-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.eu-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-west-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-west-2", - }: endpoints.Endpoint{ - Hostname: "portal.sso.eu-west-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-west-2", - }, - }, - endpoints.EndpointKey{ - Region: "eu-west-3", - }: endpoints.Endpoint{ - Hostname: "portal.sso.eu-west-3.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-west-3", - }, - }, - endpoints.EndpointKey{ - Region: "il-central-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.il-central-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "il-central-1", - }, - }, - endpoints.EndpointKey{ - Region: "me-central-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.me-central-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "me-central-1", - }, - }, - endpoints.EndpointKey{ - Region: "me-south-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.me-south-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "me-south-1", - }, - }, - endpoints.EndpointKey{ - Region: "sa-east-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.sa-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "sa-east-1", - }, - }, - endpoints.EndpointKey{ - Region: "us-east-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.us-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-east-1", - }, - }, - endpoints.EndpointKey{ - Region: "us-east-2", - }: endpoints.Endpoint{ - Hostname: "portal.sso.us-east-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-east-2", - }, - }, - endpoints.EndpointKey{ - Region: "us-west-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.us-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-west-1", - }, - }, - endpoints.EndpointKey{ - Region: "us-west-2", - }: endpoints.Endpoint{ - Hostname: "portal.sso.us-west-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-west-2", - }, - }, - }, - }, - { - ID: "aws-cn", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "portal.sso.{region}.api.amazonwebservices.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "portal.sso-fips.{region}.amazonaws.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "portal.sso-fips.{region}.api.amazonwebservices.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "portal.sso.{region}.amazonaws.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsCn, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "cn-north-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.cn-north-1.amazonaws.com.cn", - CredentialScope: endpoints.CredentialScope{ - Region: "cn-north-1", - }, - }, - endpoints.EndpointKey{ - Region: "cn-northwest-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.cn-northwest-1.amazonaws.com.cn", - CredentialScope: endpoints.CredentialScope{ - Region: "cn-northwest-1", - }, - }, - }, - }, - { - ID: "aws-iso", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "portal.sso-fips.{region}.c2s.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "portal.sso.{region}.c2s.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIso, - IsRegionalized: true, - }, - { - ID: "aws-iso-b", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "portal.sso-fips.{region}.sc2s.sgov.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "portal.sso.{region}.sc2s.sgov.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoB, - IsRegionalized: true, - }, - { - ID: "aws-iso-e", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "portal.sso-fips.{region}.cloud.adc-e.uk", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "portal.sso.{region}.cloud.adc-e.uk", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoE, - IsRegionalized: true, - }, - { - ID: "aws-iso-f", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "portal.sso-fips.{region}.csp.hci.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "portal.sso.{region}.csp.hci.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoF, - IsRegionalized: true, - }, - { - ID: "aws-us-gov", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "portal.sso.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "portal.sso-fips.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "portal.sso-fips.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "portal.sso.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsUsGov, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "us-gov-east-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.us-gov-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-gov-east-1", - }, - }, - endpoints.EndpointKey{ - Region: "us-gov-west-1", - }: endpoints.Endpoint{ - Hostname: "portal.sso.us-gov-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-gov-west-1", - }, - }, - }, - }, -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go deleted file mode 100644 index aa744f1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go +++ /dev/null @@ -1,232 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" - smithyauth "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net/http" -) - -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) -} - -type Options struct { - // Set of options to modify how an operation is invoked. These apply to all - // operations invoked for this client. Use functional options on operation call to - // modify this list for per operation behavior. - APIOptions []func(*middleware.Stack) error - - // The optional application specific identifier appended to the User-Agent header. - AppID string - - // This endpoint will be given as input to an EndpointResolverV2. It is used for - // providing a custom base endpoint that is subject to modifications by the - // processing EndpointResolverV2. - BaseEndpoint *string - - // Configures the events that will be sent to the configured logger. - ClientLogMode aws.ClientLogMode - - // The credentials object to use when signing requests. - Credentials aws.CredentialsProvider - - // The configuration DefaultsMode that the SDK should use when constructing the - // clients initial default settings. - DefaultsMode aws.DefaultsMode - - // The endpoint options to be used when attempting to resolve an endpoint. - EndpointOptions EndpointResolverOptions - - // The service endpoint resolver. - // - // Deprecated: Deprecated: EndpointResolver and WithEndpointResolver. Providing a - // value for this field will likely prevent you from using any endpoint-related - // service features released after the introduction of EndpointResolverV2 and - // BaseEndpoint. - // - // To migrate an EndpointResolver implementation that uses a custom endpoint, set - // the client option BaseEndpoint instead. - EndpointResolver EndpointResolver - - // Resolves the endpoint used for a particular service operation. This should be - // used over the deprecated EndpointResolver. - EndpointResolverV2 EndpointResolverV2 - - // Signature Version 4 (SigV4) Signer - HTTPSignerV4 HTTPSignerV4 - - // The logger writer interface to write logging messages to. - Logger logging.Logger - - // The client meter provider. - MeterProvider metrics.MeterProvider - - // The region to send requests to. (Required) - Region string - - // RetryMaxAttempts specifies the maximum number attempts an API client will call - // an operation that fails with a retryable error. A value of 0 is ignored, and - // will not be used to configure the API client created default retryer, or modify - // per operation call's retry max attempts. - // - // If specified in an operation call's functional options with a value that is - // different than the constructed client's Options, the Client's Retryer will be - // wrapped to use the operation's specific RetryMaxAttempts value. - RetryMaxAttempts int - - // RetryMode specifies the retry mode the API client will be created with, if - // Retryer option is not also specified. - // - // When creating a new API Clients this member will only be used if the Retryer - // Options member is nil. This value will be ignored if Retryer is not nil. - // - // Currently does not support per operation call overrides, may in the future. - RetryMode aws.RetryMode - - // Retryer guides how HTTP requests should be retried in case of recoverable - // failures. When nil the API client will use a default retryer. The kind of - // default retry created by the API client can be changed with the RetryMode - // option. - Retryer aws.Retryer - - // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set - // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You - // should not populate this structure programmatically, or rely on the values here - // within your applications. - RuntimeEnvironment aws.RuntimeEnvironment - - // The client tracer provider. - TracerProvider tracing.TracerProvider - - // The initial DefaultsMode used when the client options were constructed. If the - // DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved - // value was at that point in time. - // - // Currently does not support per operation call overrides, may in the future. - resolvedDefaultsMode aws.DefaultsMode - - // The HTTP client to invoke API calls with. Defaults to client's default HTTP - // implementation if nil. - HTTPClient HTTPClient - - // The auth scheme resolver which determines how to authenticate for each - // operation. - AuthSchemeResolver AuthSchemeResolver - - // The list of auth schemes supported by the client. - AuthSchemes []smithyhttp.AuthScheme -} - -// Copy creates a clone where the APIOptions list is deep copied. -func (o Options) Copy() Options { - to := o - to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) - copy(to.APIOptions, o.APIOptions) - - return to -} - -func (o Options) GetIdentityResolver(schemeID string) smithyauth.IdentityResolver { - if schemeID == "aws.auth#sigv4" { - return getSigV4IdentityResolver(o) - } - if schemeID == "smithy.api#noAuth" { - return &smithyauth.AnonymousIdentityResolver{} - } - return nil -} - -// WithAPIOptions returns a functional option for setting the Client's APIOptions -// option. -func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { - return func(o *Options) { - o.APIOptions = append(o.APIOptions, optFns...) - } -} - -// Deprecated: EndpointResolver and WithEndpointResolver. Providing a value for -// this field will likely prevent you from using any endpoint-related service -// features released after the introduction of EndpointResolverV2 and BaseEndpoint. -// -// To migrate an EndpointResolver implementation that uses a custom endpoint, set -// the client option BaseEndpoint instead. -func WithEndpointResolver(v EndpointResolver) func(*Options) { - return func(o *Options) { - o.EndpointResolver = v - } -} - -// WithEndpointResolverV2 returns a functional option for setting the Client's -// EndpointResolverV2 option. -func WithEndpointResolverV2(v EndpointResolverV2) func(*Options) { - return func(o *Options) { - o.EndpointResolverV2 = v - } -} - -func getSigV4IdentityResolver(o Options) smithyauth.IdentityResolver { - if o.Credentials != nil { - return &internalauthsmithy.CredentialsProviderAdapter{Provider: o.Credentials} - } - return nil -} - -// WithSigV4SigningName applies an override to the authentication workflow to -// use the given signing name for SigV4-authenticated operations. -// -// This is an advanced setting. The value here is FINAL, taking precedence over -// the resolved signing name from both auth scheme resolution and endpoint -// resolution. -func WithSigV4SigningName(name string) func(*Options) { - fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, - ) { - return next.HandleInitialize(awsmiddleware.SetSigningName(ctx, name), in) - } - return func(o *Options) { - o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { - return s.Initialize.Add( - middleware.InitializeMiddlewareFunc("withSigV4SigningName", fn), - middleware.Before, - ) - }) - } -} - -// WithSigV4SigningRegion applies an override to the authentication workflow to -// use the given signing region for SigV4-authenticated operations. -// -// This is an advanced setting. The value here is FINAL, taking precedence over -// the resolved signing region from both auth scheme resolution and endpoint -// resolution. -func WithSigV4SigningRegion(region string) func(*Options) { - fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, - ) { - return next.HandleInitialize(awsmiddleware.SetSigningRegion(ctx, region), in) - } - return func(o *Options) { - o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { - return s.Initialize.Add( - middleware.InitializeMiddlewareFunc("withSigV4SigningRegion", fn), - middleware.Before, - ) - }) - } -} - -func ignoreAnonymousAuth(options *Options) { - if aws.IsCredentialsProvider(options.Credentials, (*aws.AnonymousCredentials)(nil)) { - options.Credentials = nil - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/serializers.go deleted file mode 100644 index a7a5b57..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/serializers.go +++ /dev/null @@ -1,309 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "fmt" - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/encoding/httpbinding" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -type awsRestjson1_serializeOpGetRoleCredentials struct { -} - -func (*awsRestjson1_serializeOpGetRoleCredentials) ID() string { - return "OperationSerializer" -} - -func (m *awsRestjson1_serializeOpGetRoleCredentials) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetRoleCredentialsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - opPath, opQuery := httpbinding.SplitURI("/federation/credentials") - request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) - request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) - request.Method = "GET" - var restEncoder *httpbinding.Encoder - if request.URL.RawPath == "" { - restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - } else { - request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) - restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) - } - - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if err := awsRestjson1_serializeOpHttpBindingsGetRoleCredentialsInput(input, restEncoder); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = restEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} -func awsRestjson1_serializeOpHttpBindingsGetRoleCredentialsInput(v *GetRoleCredentialsInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - if v.AccessToken != nil { - locationName := "X-Amz-Sso_bearer_token" - encoder.SetHeader(locationName).String(*v.AccessToken) - } - - if v.AccountId != nil { - encoder.SetQuery("account_id").String(*v.AccountId) - } - - if v.RoleName != nil { - encoder.SetQuery("role_name").String(*v.RoleName) - } - - return nil -} - -type awsRestjson1_serializeOpListAccountRoles struct { -} - -func (*awsRestjson1_serializeOpListAccountRoles) ID() string { - return "OperationSerializer" -} - -func (m *awsRestjson1_serializeOpListAccountRoles) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListAccountRolesInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - opPath, opQuery := httpbinding.SplitURI("/assignment/roles") - request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) - request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) - request.Method = "GET" - var restEncoder *httpbinding.Encoder - if request.URL.RawPath == "" { - restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - } else { - request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) - restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) - } - - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if err := awsRestjson1_serializeOpHttpBindingsListAccountRolesInput(input, restEncoder); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = restEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} -func awsRestjson1_serializeOpHttpBindingsListAccountRolesInput(v *ListAccountRolesInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - if v.AccessToken != nil { - locationName := "X-Amz-Sso_bearer_token" - encoder.SetHeader(locationName).String(*v.AccessToken) - } - - if v.AccountId != nil { - encoder.SetQuery("account_id").String(*v.AccountId) - } - - if v.MaxResults != nil { - encoder.SetQuery("max_result").Integer(*v.MaxResults) - } - - if v.NextToken != nil { - encoder.SetQuery("next_token").String(*v.NextToken) - } - - return nil -} - -type awsRestjson1_serializeOpListAccounts struct { -} - -func (*awsRestjson1_serializeOpListAccounts) ID() string { - return "OperationSerializer" -} - -func (m *awsRestjson1_serializeOpListAccounts) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*ListAccountsInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - opPath, opQuery := httpbinding.SplitURI("/assignment/accounts") - request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) - request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) - request.Method = "GET" - var restEncoder *httpbinding.Encoder - if request.URL.RawPath == "" { - restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - } else { - request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) - restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) - } - - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if err := awsRestjson1_serializeOpHttpBindingsListAccountsInput(input, restEncoder); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = restEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} -func awsRestjson1_serializeOpHttpBindingsListAccountsInput(v *ListAccountsInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - if v.AccessToken != nil { - locationName := "X-Amz-Sso_bearer_token" - encoder.SetHeader(locationName).String(*v.AccessToken) - } - - if v.MaxResults != nil { - encoder.SetQuery("max_result").Integer(*v.MaxResults) - } - - if v.NextToken != nil { - encoder.SetQuery("next_token").String(*v.NextToken) - } - - return nil -} - -type awsRestjson1_serializeOpLogout struct { -} - -func (*awsRestjson1_serializeOpLogout) ID() string { - return "OperationSerializer" -} - -func (m *awsRestjson1_serializeOpLogout) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*LogoutInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - opPath, opQuery := httpbinding.SplitURI("/logout") - request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) - request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) - request.Method = "POST" - var restEncoder *httpbinding.Encoder - if request.URL.RawPath == "" { - restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - } else { - request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) - restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) - } - - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if err := awsRestjson1_serializeOpHttpBindingsLogoutInput(input, restEncoder); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = restEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} -func awsRestjson1_serializeOpHttpBindingsLogoutInput(v *LogoutInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - if v.AccessToken != nil { - locationName := "X-Amz-Sso_bearer_token" - encoder.SetHeader(locationName).String(*v.AccessToken) - } - - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/types/errors.go deleted file mode 100644 index e97a126..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/types/errors.go +++ /dev/null @@ -1,115 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - "fmt" - smithy "github.com/aws/smithy-go" -) - -// Indicates that a problem occurred with the input to the request. For example, a -// required parameter might be missing or out of range. -type InvalidRequestException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidRequestException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidRequestException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidRequestException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidRequestException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidRequestException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified resource doesn't exist. -type ResourceNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ResourceNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ResourceNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ResourceNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ResourceNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *ResourceNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that the request is being made too frequently and is more than what -// the server can handle. -type TooManyRequestsException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *TooManyRequestsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *TooManyRequestsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *TooManyRequestsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "TooManyRequestsException" - } - return *e.ErrorCodeOverride -} -func (e *TooManyRequestsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that the request is not authorized. This can happen due to an invalid -// access token in the request. -type UnauthorizedException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UnauthorizedException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnauthorizedException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnauthorizedException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnauthorizedException" - } - return *e.ErrorCodeOverride -} -func (e *UnauthorizedException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/types/types.go deleted file mode 100644 index 07ac468..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/types/types.go +++ /dev/null @@ -1,63 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - smithydocument "github.com/aws/smithy-go/document" -) - -// Provides information about your AWS account. -type AccountInfo struct { - - // The identifier of the AWS account that is assigned to the user. - AccountId *string - - // The display name of the AWS account that is assigned to the user. - AccountName *string - - // The email address of the AWS account that is assigned to the user. - EmailAddress *string - - noSmithyDocumentSerde -} - -// Provides information about the role credentials that are assigned to the user. -type RoleCredentials struct { - - // The identifier used for the temporary security credentials. For more - // information, see [Using Temporary Security Credentials to Request Access to AWS Resources]in the AWS IAM User Guide. - // - // [Using Temporary Security Credentials to Request Access to AWS Resources]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html - AccessKeyId *string - - // The date on which temporary security credentials expire. - Expiration int64 - - // The key that is used to sign the request. For more information, see [Using Temporary Security Credentials to Request Access to AWS Resources] in the AWS - // IAM User Guide. - // - // [Using Temporary Security Credentials to Request Access to AWS Resources]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html - SecretAccessKey *string - - // The token used for temporary credentials. For more information, see [Using Temporary Security Credentials to Request Access to AWS Resources] in the AWS - // IAM User Guide. - // - // [Using Temporary Security Credentials to Request Access to AWS Resources]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html - SessionToken *string - - noSmithyDocumentSerde -} - -// Provides information about the role that is assigned to the user. -type RoleInfo struct { - - // The identifier of the AWS account assigned to the user. - AccountId *string - - // The friendly name of the role that is assigned to the user. - RoleName *string - - noSmithyDocumentSerde -} - -type noSmithyDocumentSerde = smithydocument.NoSerde diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/validators.go deleted file mode 100644 index f6bf461..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/validators.go +++ /dev/null @@ -1,175 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sso - -import ( - "context" - "fmt" - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/middleware" -) - -type validateOpGetRoleCredentials struct { -} - -func (*validateOpGetRoleCredentials) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetRoleCredentials) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetRoleCredentialsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetRoleCredentialsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListAccountRoles struct { -} - -func (*validateOpListAccountRoles) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListAccountRoles) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListAccountRolesInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListAccountRolesInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpListAccounts struct { -} - -func (*validateOpListAccounts) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpListAccounts) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*ListAccountsInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpListAccountsInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpLogout struct { -} - -func (*validateOpLogout) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpLogout) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*LogoutInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpLogoutInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -func addOpGetRoleCredentialsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetRoleCredentials{}, middleware.After) -} - -func addOpListAccountRolesValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListAccountRoles{}, middleware.After) -} - -func addOpListAccountsValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpListAccounts{}, middleware.After) -} - -func addOpLogoutValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpLogout{}, middleware.After) -} - -func validateOpGetRoleCredentialsInput(v *GetRoleCredentialsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetRoleCredentialsInput"} - if v.RoleName == nil { - invalidParams.Add(smithy.NewErrParamRequired("RoleName")) - } - if v.AccountId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AccountId")) - } - if v.AccessToken == nil { - invalidParams.Add(smithy.NewErrParamRequired("AccessToken")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListAccountRolesInput(v *ListAccountRolesInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListAccountRolesInput"} - if v.AccessToken == nil { - invalidParams.Add(smithy.NewErrParamRequired("AccessToken")) - } - if v.AccountId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AccountId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpListAccountsInput(v *ListAccountsInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "ListAccountsInput"} - if v.AccessToken == nil { - invalidParams.Add(smithy.NewErrParamRequired("AccessToken")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpLogoutInput(v *LogoutInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "LogoutInput"} - if v.AccessToken == nil { - invalidParams.Add(smithy.NewErrParamRequired("AccessToken")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md deleted file mode 100644 index 29bce60..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md +++ /dev/null @@ -1,567 +0,0 @@ -# v1.28.13 (2025-01-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.12 (2025-01-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.11 (2025-01-24) - -* **Documentation**: Fixed typos in the descriptions. -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v1.28.10 (2025-01-17) - -* **Bug Fix**: Fix bug where credentials weren't refreshed during retry loop. - -# v1.28.9 (2025-01-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.8 (2025-01-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.7 (2024-12-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.6 (2024-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.5 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.4 (2024-11-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.3 (2024-10-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.2 (2024-10-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.1 (2024-10-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.0 (2024-10-04) - -* **Feature**: Add support for HTTP client metrics. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.4 (2024-10-03) - -* No change notes available for this release. - -# v1.27.3 (2024-09-27) - -* No change notes available for this release. - -# v1.27.2 (2024-09-25) - -* No change notes available for this release. - -# v1.27.1 (2024-09-23) - -* No change notes available for this release. - -# v1.27.0 (2024-09-20) - -* **Feature**: Add tracing and metrics support to service clients. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.8 (2024-09-17) - -* **Bug Fix**: **BREAKFIX**: Only generate AccountIDEndpointMode config for services that use it. This is a compiler break, but removes no actual functionality, as no services currently use the account ID in endpoint resolution. - -# v1.26.7 (2024-09-04) - -* No change notes available for this release. - -# v1.26.6 (2024-09-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.5 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.4 (2024-07-10.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.3 (2024-07-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.2 (2024-07-03) - -* No change notes available for this release. - -# v1.26.1 (2024-06-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.0 (2024-06-26) - -* **Feature**: Support list-of-string endpoint parameter. - -# v1.25.1 (2024-06-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.0 (2024-06-18) - -* **Feature**: Track usage of various AWS SDK features in user-agent string. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.6 (2024-06-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.5 (2024-06-07) - -* **Bug Fix**: Add clock skew correction on all service clients -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.4 (2024-06-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.3 (2024-05-23) - -* No change notes available for this release. - -# v1.24.2 (2024-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.1 (2024-05-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.0 (2024-05-10) - -* **Feature**: Updated request parameters for PKCE support. - -# v1.23.5 (2024-05-08) - -* **Bug Fix**: GoDoc improvement - -# v1.23.4 (2024-03-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.3 (2024-03-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.2 (2024-03-07) - -* **Bug Fix**: Remove dependency on go-cmp. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.1 (2024-02-23) - -* **Bug Fix**: Move all common, SDK-side middleware stack ops into the service client module to prevent cross-module compatibility issues in the future. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.0 (2024-02-22) - -* **Feature**: Add middleware stack snapshot tests. - -# v1.22.2 (2024-02-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.22.1 (2024-02-20) - -* **Bug Fix**: When sourcing values for a service's `EndpointParameters`, the lack of a configured region (i.e. `options.Region == ""`) will now translate to a `nil` value for `EndpointParameters.Region` instead of a pointer to the empty string `""`. This will result in a much more explicit error when calling an operation instead of an obscure hostname lookup failure. - -# v1.22.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.7 (2024-01-16) - -* No change notes available for this release. - -# v1.21.6 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.5 (2023-12-08) - -* **Bug Fix**: Reinstate presence of default Retryer in functional options, but still respect max attempts set therein. - -# v1.21.4 (2023-12-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.3 (2023-12-06) - -* **Bug Fix**: Restore pre-refactor auth behavior where all operations could technically be performed anonymously. - -# v1.21.2 (2023-12-01) - -* **Bug Fix**: Correct wrapping of errors in authentication workflow. -* **Bug Fix**: Correctly recognize cache-wrapped instances of AnonymousCredentials at client construction. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.1 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.0 (2023-11-29) - -* **Feature**: Expose Options() accessor on service clients. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.3 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.2 (2023-11-28) - -* **Bug Fix**: Respect setting RetryMaxAttempts in functional options at client construction. - -# v1.20.1 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.0 (2023-11-17) - -* **Feature**: Adding support for `sso-oauth:CreateTokenWithIAM`. - -# v1.19.2 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.19.1 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.19.0 (2023-11-01) - -* **Feature**: Adds support for configured endpoints via environment variables and the AWS shared configuration file. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.3 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.2 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.1 (2023-09-22) - -* No change notes available for this release. - -# v1.17.0 (2023-09-20) - -* **Feature**: Update FIPS endpoints in aws-us-gov. - -# v1.16.0 (2023-09-18) - -* **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. -* **Feature**: Adds several endpoint ruleset changes across all models: smaller rulesets, removed non-unique regional endpoints, fixes FIPS and DualStack endpoints, and make region not required in SDK::Endpoint. Additional breakfix to cognito-sync field. - -# v1.15.6 (2023-09-05) - -* No change notes available for this release. - -# v1.15.5 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.4 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.3 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.2 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.1 (2023-08-01) - -* No change notes available for this release. - -# v1.15.0 (2023-07-31) - -* **Feature**: Adds support for smithy-modeled endpoint resolution. A new rules-based endpoint resolution will be added to the SDK which will supercede and deprecate existing endpoint resolution. Specifically, EndpointResolver will be deprecated while BaseEndpoint and EndpointResolverV2 will take its place. For more information, please see the Endpoints section in our Developer Guide. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.14 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.13 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.12 (2023-06-15) - -* No change notes available for this release. - -# v1.14.11 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.10 (2023-05-04) - -* No change notes available for this release. - -# v1.14.9 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.8 (2023-04-10) - -* No change notes available for this release. - -# v1.14.7 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.6 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.5 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.4 (2023-02-22) - -* **Bug Fix**: Prevent nil pointer dereference when retrieving error codes. - -# v1.14.3 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.2 (2023-02-15) - -* **Announcement**: When receiving an error response in restJson-based services, an incorrect error type may have been returned based on the content of the response. This has been fixed via PR #2012 tracked in issue #1910. -* **Bug Fix**: Correct error type parsing for restJson services. - -# v1.14.1 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.0 (2023-01-05) - -* **Feature**: Add `ErrorCodeOverride` field to all error structs (aws/smithy-go#401). - -# v1.13.11 (2022-12-19) - -* No change notes available for this release. - -# v1.13.10 (2022-12-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.9 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.8 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.7 (2022-10-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.6 (2022-09-30) - -* **Documentation**: Documentation updates for the IAM Identity Center OIDC CLI Reference. - -# v1.13.5 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.4 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.3 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.2 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.1 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.0 (2022-08-25) - -* **Feature**: Updated required request parameters on IAM Identity Center's OIDC CreateToken action. - -# v1.12.14 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.13 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.12 (2022-08-08) - -* **Documentation**: Documentation updates to reflect service rename - AWS IAM Identity Center (successor to AWS Single Sign-On) -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.11 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.10 (2022-07-11) - -* No change notes available for this release. - -# v1.12.9 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.8 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.7 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.6 (2022-05-27) - -* No change notes available for this release. - -# v1.12.5 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.4 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.3 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.2 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.1 (2022-03-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.0 (2022-02-24) - -* **Feature**: API client updated -* **Feature**: Adds RetryMaxAttempts and RetryMod to API client Options. This allows the API clients' default Retryer to be configured from the shared configuration files or environment variables. Adding a new Retry mode of `Adaptive`. `Adaptive` retry mode is an experimental mode, adding client rate limiting when throttles reponses are received from an API. See [retry.AdaptiveMode](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AdaptiveMode) for more details, and configuration options. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.0 (2022-01-14) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.9.0 (2022-01-07) - -* **Feature**: API client updated -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.2 (2021-12-02) - -* **Bug Fix**: Fixes a bug that prevented aws.EndpointResolverWithOptions from being used by the service client. ([#1514](https://github.com/aws/aws-sdk-go-v2/pull/1514)) -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.1 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.0 (2021-11-06) - -* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.7.0 (2021-10-21) - -* **Feature**: Updated to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.0 (2021-10-11) - -* **Feature**: API client updated -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.0 (2021-09-17) - -* **Feature**: Updated API client and endpoints to latest revision. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.0 (2021-08-27) - -* **Feature**: Updated API model to latest revision. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.3 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.2 (2021-08-04) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.1 (2021-07-15) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.3.0 (2021-06-25) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.1 (2021-05-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.2.0 (2021-05-14) - -* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting. -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go deleted file mode 100644 index 9b7f4ac..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go +++ /dev/null @@ -1,912 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "context" - "errors" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/aws/defaults" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/retry" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" - internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" - internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" - internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" - internalmiddleware "github.com/aws/aws-sdk-go-v2/internal/middleware" - smithy "github.com/aws/smithy-go" - smithyauth "github.com/aws/smithy-go/auth" - smithydocument "github.com/aws/smithy-go/document" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net" - "net/http" - "sync/atomic" - "time" -) - -const ServiceID = "SSO OIDC" -const ServiceAPIVersion = "2019-06-10" - -type operationMetrics struct { - Duration metrics.Float64Histogram - SerializeDuration metrics.Float64Histogram - ResolveIdentityDuration metrics.Float64Histogram - ResolveEndpointDuration metrics.Float64Histogram - SignRequestDuration metrics.Float64Histogram - DeserializeDuration metrics.Float64Histogram -} - -func (m *operationMetrics) histogramFor(name string) metrics.Float64Histogram { - switch name { - case "client.call.duration": - return m.Duration - case "client.call.serialization_duration": - return m.SerializeDuration - case "client.call.resolve_identity_duration": - return m.ResolveIdentityDuration - case "client.call.resolve_endpoint_duration": - return m.ResolveEndpointDuration - case "client.call.signing_duration": - return m.SignRequestDuration - case "client.call.deserialization_duration": - return m.DeserializeDuration - default: - panic("unrecognized operation metric") - } -} - -func timeOperationMetric[T any]( - ctx context.Context, metric string, fn func() (T, error), - opts ...metrics.RecordMetricOption, -) (T, error) { - instr := getOperationMetrics(ctx).histogramFor(metric) - opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) - - start := time.Now() - v, err := fn() - end := time.Now() - - elapsed := end.Sub(start) - instr.Record(ctx, float64(elapsed)/1e9, opts...) - return v, err -} - -func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() { - instr := getOperationMetrics(ctx).histogramFor(metric) - opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) - - var ended bool - start := time.Now() - return func() { - if ended { - return - } - ended = true - - end := time.Now() - - elapsed := end.Sub(start) - instr.Record(ctx, float64(elapsed)/1e9, opts...) - } -} - -func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { - return func(o *metrics.RecordMetricOptions) { - o.Properties.Set("rpc.service", middleware.GetServiceID(ctx)) - o.Properties.Set("rpc.method", middleware.GetOperationName(ctx)) - } -} - -type operationMetricsKey struct{} - -func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) { - meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/ssooidc") - om := &operationMetrics{} - - var err error - - om.Duration, err = operationMetricTimer(meter, "client.call.duration", - "Overall call duration (including retries and time to send or receive request and response body)") - if err != nil { - return nil, err - } - om.SerializeDuration, err = operationMetricTimer(meter, "client.call.serialization_duration", - "The time it takes to serialize a message body") - if err != nil { - return nil, err - } - om.ResolveIdentityDuration, err = operationMetricTimer(meter, "client.call.auth.resolve_identity_duration", - "The time taken to acquire an identity (AWS credentials, bearer token, etc) from an Identity Provider") - if err != nil { - return nil, err - } - om.ResolveEndpointDuration, err = operationMetricTimer(meter, "client.call.resolve_endpoint_duration", - "The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request") - if err != nil { - return nil, err - } - om.SignRequestDuration, err = operationMetricTimer(meter, "client.call.auth.signing_duration", - "The time it takes to sign a request") - if err != nil { - return nil, err - } - om.DeserializeDuration, err = operationMetricTimer(meter, "client.call.deserialization_duration", - "The time it takes to deserialize a message body") - if err != nil { - return nil, err - } - - return context.WithValue(parent, operationMetricsKey{}, om), nil -} - -func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Histogram, error) { - return m.Float64Histogram(name, func(o *metrics.InstrumentOptions) { - o.UnitLabel = "s" - o.Description = desc - }) -} - -func getOperationMetrics(ctx context.Context) *operationMetrics { - return ctx.Value(operationMetricsKey{}).(*operationMetrics) -} - -func operationTracer(p tracing.TracerProvider) tracing.Tracer { - return p.Tracer("github.com/aws/aws-sdk-go-v2/service/ssooidc") -} - -// Client provides the API client to make operations call for AWS SSO OIDC. -type Client struct { - options Options - - // Difference between the time reported by the server and the client - timeOffset *atomic.Int64 -} - -// New returns an initialized Client based on the functional options. Provide -// additional functional options to further configure the behavior of the client, -// such as changing the client's endpoint or adding custom middleware behavior. -func New(options Options, optFns ...func(*Options)) *Client { - options = options.Copy() - - resolveDefaultLogger(&options) - - setResolvedDefaultsMode(&options) - - resolveRetryer(&options) - - resolveHTTPClient(&options) - - resolveHTTPSignerV4(&options) - - resolveEndpointResolverV2(&options) - - resolveTracerProvider(&options) - - resolveMeterProvider(&options) - - resolveAuthSchemeResolver(&options) - - for _, fn := range optFns { - fn(&options) - } - - finalizeRetryMaxAttempts(&options) - - ignoreAnonymousAuth(&options) - - wrapWithAnonymousAuth(&options) - - resolveAuthSchemes(&options) - - client := &Client{ - options: options, - } - - initializeTimeOffsetResolver(client) - - return client -} - -// Options returns a copy of the client configuration. -// -// Callers SHOULD NOT perform mutations on any inner structures within client -// config. Config overrides should instead be made on a per-operation basis through -// functional options. -func (c *Client) Options() Options { - return c.options.Copy() -} - -func (c *Client) invokeOperation( - ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error, -) ( - result interface{}, metadata middleware.Metadata, err error, -) { - ctx = middleware.ClearStackValues(ctx) - ctx = middleware.WithServiceID(ctx, ServiceID) - ctx = middleware.WithOperationName(ctx, opID) - - stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) - options := c.options.Copy() - - for _, fn := range optFns { - fn(&options) - } - - finalizeOperationRetryMaxAttempts(&options, *c) - - finalizeClientEndpointResolverOptions(&options) - - for _, fn := range stackFns { - if err := fn(stack, options); err != nil { - return nil, metadata, err - } - } - - for _, fn := range options.APIOptions { - if err := fn(stack); err != nil { - return nil, metadata, err - } - } - - ctx, err = withOperationMetrics(ctx, options.MeterProvider) - if err != nil { - return nil, metadata, err - } - - tracer := operationTracer(options.TracerProvider) - spanName := fmt.Sprintf("%s.%s", ServiceID, opID) - - ctx = tracing.WithOperationTracer(ctx, tracer) - - ctx, span := tracer.StartSpan(ctx, spanName, func(o *tracing.SpanOptions) { - o.Kind = tracing.SpanKindClient - o.Properties.Set("rpc.system", "aws-api") - o.Properties.Set("rpc.method", opID) - o.Properties.Set("rpc.service", ServiceID) - }) - endTimer := startMetricTimer(ctx, "client.call.duration") - defer endTimer() - defer span.End() - - handler := smithyhttp.NewClientHandlerWithOptions(options.HTTPClient, func(o *smithyhttp.ClientHandler) { - o.Meter = options.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/ssooidc") - }) - decorated := middleware.DecorateHandler(handler, stack) - result, metadata, err = decorated.Handle(ctx, params) - if err != nil { - span.SetProperty("exception.type", fmt.Sprintf("%T", err)) - span.SetProperty("exception.message", err.Error()) - - var aerr smithy.APIError - if errors.As(err, &aerr) { - span.SetProperty("api.error_code", aerr.ErrorCode()) - span.SetProperty("api.error_message", aerr.ErrorMessage()) - span.SetProperty("api.error_fault", aerr.ErrorFault().String()) - } - - err = &smithy.OperationError{ - ServiceID: ServiceID, - OperationName: opID, - Err: err, - } - } - - span.SetProperty("error", err != nil) - if err == nil { - span.SetStatus(tracing.SpanStatusOK) - } else { - span.SetStatus(tracing.SpanStatusError) - } - - return result, metadata, err -} - -type operationInputKey struct{} - -func setOperationInput(ctx context.Context, input interface{}) context.Context { - return middleware.WithStackValue(ctx, operationInputKey{}, input) -} - -func getOperationInput(ctx context.Context) interface{} { - return middleware.GetStackValue(ctx, operationInputKey{}) -} - -type setOperationInputMiddleware struct { -} - -func (*setOperationInputMiddleware) ID() string { - return "setOperationInput" -} - -func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - ctx = setOperationInput(ctx, in.Parameters) - return next.HandleSerialize(ctx, in) -} - -func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error { - if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil { - return fmt.Errorf("add ResolveAuthScheme: %w", err) - } - if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil { - return fmt.Errorf("add GetIdentity: %v", err) - } - if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil { - return fmt.Errorf("add ResolveEndpointV2: %v", err) - } - if err := stack.Finalize.Insert(&signRequestMiddleware{options: options}, "ResolveEndpointV2", middleware.After); err != nil { - return fmt.Errorf("add Signing: %w", err) - } - return nil -} -func resolveAuthSchemeResolver(options *Options) { - if options.AuthSchemeResolver == nil { - options.AuthSchemeResolver = &defaultAuthSchemeResolver{} - } -} - -func resolveAuthSchemes(options *Options) { - if options.AuthSchemes == nil { - options.AuthSchemes = []smithyhttp.AuthScheme{ - internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{ - Signer: options.HTTPSignerV4, - Logger: options.Logger, - LogSigning: options.ClientLogMode.IsSigning(), - }), - } - } -} - -type noSmithyDocumentSerde = smithydocument.NoSerde - -type legacyEndpointContextSetter struct { - LegacyResolver EndpointResolver -} - -func (*legacyEndpointContextSetter) ID() string { - return "legacyEndpointContextSetter" -} - -func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.LegacyResolver != nil { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) - } - - return next.HandleInitialize(ctx, in) - -} -func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { - return stack.Initialize.Add(&legacyEndpointContextSetter{ - LegacyResolver: o.EndpointResolver, - }, middleware.Before) -} - -func resolveDefaultLogger(o *Options) { - if o.Logger != nil { - return - } - o.Logger = logging.Nop{} -} - -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) -} - -func setResolvedDefaultsMode(o *Options) { - if len(o.resolvedDefaultsMode) > 0 { - return - } - - var mode aws.DefaultsMode - mode.SetFromString(string(o.DefaultsMode)) - - if mode == aws.DefaultsModeAuto { - mode = defaults.ResolveDefaultsModeAuto(o.Region, o.RuntimeEnvironment) - } - - o.resolvedDefaultsMode = mode -} - -// NewFromConfig returns a new client from the provided config. -func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { - opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, - } - resolveAWSRetryerProvider(cfg, &opts) - resolveAWSRetryMaxAttempts(cfg, &opts) - resolveAWSRetryMode(cfg, &opts) - resolveAWSEndpointResolver(cfg, &opts) - resolveUseDualStackEndpoint(cfg, &opts) - resolveUseFIPSEndpoint(cfg, &opts) - resolveBaseEndpoint(cfg, &opts) - return New(opts, optFns...) -} - -func resolveHTTPClient(o *Options) { - var buildable *awshttp.BuildableClient - - if o.HTTPClient != nil { - var ok bool - buildable, ok = o.HTTPClient.(*awshttp.BuildableClient) - if !ok { - return - } - } else { - buildable = awshttp.NewBuildableClient() - } - - modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) - if err == nil { - buildable = buildable.WithDialerOptions(func(dialer *net.Dialer) { - if dialerTimeout, ok := modeConfig.GetConnectTimeout(); ok { - dialer.Timeout = dialerTimeout - } - }) - - buildable = buildable.WithTransportOptions(func(transport *http.Transport) { - if tlsHandshakeTimeout, ok := modeConfig.GetTLSNegotiationTimeout(); ok { - transport.TLSHandshakeTimeout = tlsHandshakeTimeout - } - }) - } - - o.HTTPClient = buildable -} - -func resolveRetryer(o *Options) { - if o.Retryer != nil { - return - } - - if len(o.RetryMode) == 0 { - modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) - if err == nil { - o.RetryMode = modeConfig.RetryMode - } - } - if len(o.RetryMode) == 0 { - o.RetryMode = aws.RetryModeStandard - } - - var standardOptions []func(*retry.StandardOptions) - if v := o.RetryMaxAttempts; v != 0 { - standardOptions = append(standardOptions, func(so *retry.StandardOptions) { - so.MaxAttempts = v - }) - } - - switch o.RetryMode { - case aws.RetryModeAdaptive: - var adaptiveOptions []func(*retry.AdaptiveModeOptions) - if len(standardOptions) != 0 { - adaptiveOptions = append(adaptiveOptions, func(ao *retry.AdaptiveModeOptions) { - ao.StandardOptions = append(ao.StandardOptions, standardOptions...) - }) - } - o.Retryer = retry.NewAdaptiveMode(adaptiveOptions...) - - default: - o.Retryer = retry.NewStandard(standardOptions...) - } -} - -func resolveAWSRetryerProvider(cfg aws.Config, o *Options) { - if cfg.Retryer == nil { - return - } - o.Retryer = cfg.Retryer() -} - -func resolveAWSRetryMode(cfg aws.Config, o *Options) { - if len(cfg.RetryMode) == 0 { - return - } - o.RetryMode = cfg.RetryMode -} -func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) { - if cfg.RetryMaxAttempts == 0 { - return - } - o.RetryMaxAttempts = cfg.RetryMaxAttempts -} - -func finalizeRetryMaxAttempts(o *Options) { - if o.RetryMaxAttempts == 0 { - return - } - - o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) -} - -func finalizeOperationRetryMaxAttempts(o *Options, client Client) { - if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts { - return - } - - o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) -} - -func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { - if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { - return - } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) -} - -func addClientUserAgent(stack *middleware.Stack, options Options) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - ua.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ssooidc", goModuleVersion) - if len(options.AppID) > 0 { - ua.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID) - } - - return nil -} - -func getOrAddRequestUserAgent(stack *middleware.Stack) (*awsmiddleware.RequestUserAgent, error) { - id := (*awsmiddleware.RequestUserAgent)(nil).ID() - mw, ok := stack.Build.Get(id) - if !ok { - mw = awsmiddleware.NewRequestUserAgent() - if err := stack.Build.Add(mw, middleware.After); err != nil { - return nil, err - } - } - - ua, ok := mw.(*awsmiddleware.RequestUserAgent) - if !ok { - return nil, fmt.Errorf("%T for %s middleware did not match expected type", mw, id) - } - - return ua, nil -} - -type HTTPSignerV4 interface { - SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error -} - -func resolveHTTPSignerV4(o *Options) { - if o.HTTPSignerV4 != nil { - return - } - o.HTTPSignerV4 = newDefaultV4Signer(*o) -} - -func newDefaultV4Signer(o Options) *v4.Signer { - return v4.NewSigner(func(so *v4.SignerOptions) { - so.Logger = o.Logger - so.LogSigning = o.ClientLogMode.IsSigning() - }) -} - -func addClientRequestID(stack *middleware.Stack) error { - return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) -} - -func addComputeContentLength(stack *middleware.Stack) error { - return stack.Build.Add(&smithyhttp.ComputeContentLength{}, middleware.After) -} - -func addRawResponseToMetadata(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) -} - -func addRecordResponseTiming(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) -} - -func addSpanRetryLoop(stack *middleware.Stack, options Options) error { - return stack.Finalize.Insert(&spanRetryLoop{options: options}, "Retry", middleware.Before) -} - -type spanRetryLoop struct { - options Options -} - -func (*spanRetryLoop) ID() string { - return "spanRetryLoop" -} - -func (m *spanRetryLoop) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - middleware.FinalizeOutput, middleware.Metadata, error, -) { - tracer := operationTracer(m.options.TracerProvider) - ctx, span := tracer.StartSpan(ctx, "RetryLoop") - defer span.End() - - return next.HandleFinalize(ctx, in) -} -func addStreamingEventsPayload(stack *middleware.Stack) error { - return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before) -} - -func addUnsignedPayload(stack *middleware.Stack) error { - return stack.Finalize.Insert(&v4.UnsignedPayload{}, "ResolveEndpointV2", middleware.After) -} - -func addComputePayloadSHA256(stack *middleware.Stack) error { - return stack.Finalize.Insert(&v4.ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After) -} - -func addContentSHA256Header(stack *middleware.Stack) error { - return stack.Finalize.Insert(&v4.ContentSHA256Header{}, (*v4.ComputePayloadSHA256)(nil).ID(), middleware.After) -} - -func addIsWaiterUserAgent(o *Options) { - o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureWaiter) - return nil - }) -} - -func addIsPaginatorUserAgent(o *Options) { - o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeaturePaginator) - return nil - }) -} - -func addRetry(stack *middleware.Stack, o Options) error { - attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) { - m.LogAttempts = o.ClientLogMode.IsRetries() - m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/ssooidc") - }) - if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { - return err - } - if err := stack.Finalize.Insert(&retry.MetricsHeader{}, attempt.ID(), middleware.After); err != nil { - return err - } - return nil -} - -// resolves dual-stack endpoint configuration -func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error { - if len(cfg.ConfigSources) == 0 { - return nil - } - value, found, err := internalConfig.ResolveUseDualStackEndpoint(context.Background(), cfg.ConfigSources) - if err != nil { - return err - } - if found { - o.EndpointOptions.UseDualStackEndpoint = value - } - return nil -} - -// resolves FIPS endpoint configuration -func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error { - if len(cfg.ConfigSources) == 0 { - return nil - } - value, found, err := internalConfig.ResolveUseFIPSEndpoint(context.Background(), cfg.ConfigSources) - if err != nil { - return err - } - if found { - o.EndpointOptions.UseFIPSEndpoint = value - } - return nil -} - -func resolveAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) *string { - if mode == aws.AccountIDEndpointModeDisabled { - return nil - } - - if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); ok && ca.Credentials.AccountID != "" { - return aws.String(ca.Credentials.AccountID) - } - - return nil -} - -func addTimeOffsetBuild(stack *middleware.Stack, c *Client) error { - mw := internalmiddleware.AddTimeOffsetMiddleware{Offset: c.timeOffset} - if err := stack.Build.Add(&mw, middleware.After); err != nil { - return err - } - return stack.Deserialize.Insert(&mw, "RecordResponseTiming", middleware.Before) -} -func initializeTimeOffsetResolver(c *Client) { - c.timeOffset = new(atomic.Int64) -} - -func addUserAgentRetryMode(stack *middleware.Stack, options Options) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - switch options.Retryer.(type) { - case *retry.Standard: - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeStandard) - case *retry.AdaptiveMode: - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeAdaptive) - } - return nil -} - -func resolveTracerProvider(options *Options) { - if options.TracerProvider == nil { - options.TracerProvider = &tracing.NopTracerProvider{} - } -} - -func resolveMeterProvider(options *Options) { - if options.MeterProvider == nil { - options.MeterProvider = metrics.NopMeterProvider{} - } -} - -func addRecursionDetection(stack *middleware.Stack) error { - return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After) -} - -func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error { - return stack.Deserialize.Insert(&awsmiddleware.RequestIDRetriever{}, "OperationDeserializer", middleware.Before) - -} - -func addResponseErrorMiddleware(stack *middleware.Stack) error { - return stack.Deserialize.Insert(&awshttp.ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before) - -} - -func addRequestResponseLogging(stack *middleware.Stack, o Options) error { - return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{ - LogRequest: o.ClientLogMode.IsRequest(), - LogRequestWithBody: o.ClientLogMode.IsRequestWithBody(), - LogResponse: o.ClientLogMode.IsResponse(), - LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), - }, middleware.After) -} - -type disableHTTPSMiddleware struct { - DisableHTTPS bool -} - -func (*disableHTTPSMiddleware) ID() string { - return "disableHTTPS" -} - -func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { - req.URL.Scheme = "http" - } - - return next.HandleFinalize(ctx, in) -} - -func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { - return stack.Finalize.Insert(&disableHTTPSMiddleware{ - DisableHTTPS: o.EndpointOptions.DisableHTTPS, - }, "ResolveEndpointV2", middleware.After) -} - -type spanInitializeStart struct { -} - -func (*spanInitializeStart) ID() string { - return "spanInitializeStart" -} - -func (m *spanInitializeStart) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "Initialize") - - return next.HandleInitialize(ctx, in) -} - -type spanInitializeEnd struct { -} - -func (*spanInitializeEnd) ID() string { - return "spanInitializeEnd" -} - -func (m *spanInitializeEnd) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleInitialize(ctx, in) -} - -type spanBuildRequestStart struct { -} - -func (*spanBuildRequestStart) ID() string { - return "spanBuildRequestStart" -} - -func (m *spanBuildRequestStart) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - middleware.SerializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "BuildRequest") - - return next.HandleSerialize(ctx, in) -} - -type spanBuildRequestEnd struct { -} - -func (*spanBuildRequestEnd) ID() string { - return "spanBuildRequestEnd" -} - -func (m *spanBuildRequestEnd) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - middleware.BuildOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleBuild(ctx, in) -} - -func addSpanInitializeStart(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeStart{}, middleware.Before) -} - -func addSpanInitializeEnd(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeEnd{}, middleware.After) -} - -func addSpanBuildRequestStart(stack *middleware.Stack) error { - return stack.Serialize.Add(&spanBuildRequestStart{}, middleware.Before) -} - -func addSpanBuildRequestEnd(stack *middleware.Stack) error { - return stack.Build.Add(&spanBuildRequestEnd{}, middleware.After) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go deleted file mode 100644 index 2ab3524..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go +++ /dev/null @@ -1,239 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Creates and returns access and refresh tokens for clients that are -// authenticated using client secrets. The access token can be used to fetch -// short-lived credentials for the assigned AWS accounts or to access application -// APIs using bearer authentication. -func (c *Client) CreateToken(ctx context.Context, params *CreateTokenInput, optFns ...func(*Options)) (*CreateTokenOutput, error) { - if params == nil { - params = &CreateTokenInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateToken", params, optFns, c.addOperationCreateTokenMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateTokenOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateTokenInput struct { - - // The unique identifier string for the client or application. This value comes - // from the result of the RegisterClientAPI. - // - // This member is required. - ClientId *string - - // A secret string generated for the client. This value should come from the - // persisted result of the RegisterClientAPI. - // - // This member is required. - ClientSecret *string - - // Supports the following OAuth grant types: Authorization Code, Device Code, and - // Refresh Token. Specify one of the following values, depending on the grant type - // that you want: - // - // * Authorization Code - authorization_code - // - // * Device Code - urn:ietf:params:oauth:grant-type:device_code - // - // * Refresh Token - refresh_token - // - // This member is required. - GrantType *string - - // Used only when calling this API for the Authorization Code grant type. The - // short-lived code is used to identify this authorization request. - Code *string - - // Used only when calling this API for the Authorization Code grant type. This - // value is generated by the client and presented to validate the original code - // challenge value the client passed at authorization time. - CodeVerifier *string - - // Used only when calling this API for the Device Code grant type. This - // short-lived code is used to identify this authorization request. This comes from - // the result of the StartDeviceAuthorizationAPI. - DeviceCode *string - - // Used only when calling this API for the Authorization Code grant type. This - // value specifies the location of the client or application that has registered to - // receive the authorization code. - RedirectUri *string - - // Used only when calling this API for the Refresh Token grant type. This token is - // used to refresh short-lived tokens, such as the access token, that might expire. - // - // For more information about the features and limitations of the current IAM - // Identity Center OIDC implementation, see Considerations for Using this Guide in - // the [IAM Identity Center OIDC API Reference]. - // - // [IAM Identity Center OIDC API Reference]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/Welcome.html - RefreshToken *string - - // The list of scopes for which authorization is requested. The access token that - // is issued is limited to the scopes that are granted. If this value is not - // specified, IAM Identity Center authorizes all scopes that are configured for the - // client during the call to RegisterClient. - Scope []string - - noSmithyDocumentSerde -} - -type CreateTokenOutput struct { - - // A bearer token to access Amazon Web Services accounts and applications assigned - // to a user. - AccessToken *string - - // Indicates the time in seconds when an access token will expire. - ExpiresIn int32 - - // The idToken is not implemented or supported. For more information about the - // features and limitations of the current IAM Identity Center OIDC implementation, - // see Considerations for Using this Guide in the [IAM Identity Center OIDC API Reference]. - // - // A JSON Web Token (JWT) that identifies who is associated with the issued access - // token. - // - // [IAM Identity Center OIDC API Reference]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/Welcome.html - IdToken *string - - // A token that, if present, can be used to refresh a previously issued access - // token that might have expired. - // - // For more information about the features and limitations of the current IAM - // Identity Center OIDC implementation, see Considerations for Using this Guide in - // the [IAM Identity Center OIDC API Reference]. - // - // [IAM Identity Center OIDC API Reference]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/Welcome.html - RefreshToken *string - - // Used to notify the client that the returned token is an access token. The - // supported token type is Bearer . - TokenType *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsRestjson1_serializeOpCreateToken{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsRestjson1_deserializeOpCreateToken{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateToken"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addOpCreateTokenValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateToken(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { - return err - } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCreateToken(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateToken", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go deleted file mode 100644 index e5253ce..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go +++ /dev/null @@ -1,271 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Creates and returns access and refresh tokens for clients and applications that -// are authenticated using IAM entities. The access token can be used to fetch -// short-lived credentials for the assigned Amazon Web Services accounts or to -// access application APIs using bearer authentication. -func (c *Client) CreateTokenWithIAM(ctx context.Context, params *CreateTokenWithIAMInput, optFns ...func(*Options)) (*CreateTokenWithIAMOutput, error) { - if params == nil { - params = &CreateTokenWithIAMInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "CreateTokenWithIAM", params, optFns, c.addOperationCreateTokenWithIAMMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*CreateTokenWithIAMOutput) - out.ResultMetadata = metadata - return out, nil -} - -type CreateTokenWithIAMInput struct { - - // The unique identifier string for the client or application. This value is an - // application ARN that has OAuth grants configured. - // - // This member is required. - ClientId *string - - // Supports the following OAuth grant types: Authorization Code, Refresh Token, - // JWT Bearer, and Token Exchange. Specify one of the following values, depending - // on the grant type that you want: - // - // * Authorization Code - authorization_code - // - // * Refresh Token - refresh_token - // - // * JWT Bearer - urn:ietf:params:oauth:grant-type:jwt-bearer - // - // * Token Exchange - urn:ietf:params:oauth:grant-type:token-exchange - // - // This member is required. - GrantType *string - - // Used only when calling this API for the JWT Bearer grant type. This value - // specifies the JSON Web Token (JWT) issued by a trusted token issuer. To - // authorize a trusted token issuer, configure the JWT Bearer GrantOptions for the - // application. - Assertion *string - - // Used only when calling this API for the Authorization Code grant type. This - // short-lived code is used to identify this authorization request. The code is - // obtained through a redirect from IAM Identity Center to a redirect URI persisted - // in the Authorization Code GrantOptions for the application. - Code *string - - // Used only when calling this API for the Authorization Code grant type. This - // value is generated by the client and presented to validate the original code - // challenge value the client passed at authorization time. - CodeVerifier *string - - // Used only when calling this API for the Authorization Code grant type. This - // value specifies the location of the client or application that has registered to - // receive the authorization code. - RedirectUri *string - - // Used only when calling this API for the Refresh Token grant type. This token is - // used to refresh short-lived tokens, such as the access token, that might expire. - // - // For more information about the features and limitations of the current IAM - // Identity Center OIDC implementation, see Considerations for Using this Guide in - // the [IAM Identity Center OIDC API Reference]. - // - // [IAM Identity Center OIDC API Reference]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/Welcome.html - RefreshToken *string - - // Used only when calling this API for the Token Exchange grant type. This value - // specifies the type of token that the requester can receive. The following values - // are supported: - // - // * Access Token - urn:ietf:params:oauth:token-type:access_token - // - // * Refresh Token - urn:ietf:params:oauth:token-type:refresh_token - RequestedTokenType *string - - // The list of scopes for which authorization is requested. The access token that - // is issued is limited to the scopes that are granted. If the value is not - // specified, IAM Identity Center authorizes all scopes configured for the - // application, including the following default scopes: openid , aws , - // sts:identity_context . - Scope []string - - // Used only when calling this API for the Token Exchange grant type. This value - // specifies the subject of the exchange. The value of the subject token must be an - // access token issued by IAM Identity Center to a different client or application. - // The access token must have authorized scopes that indicate the requested - // application as a target audience. - SubjectToken *string - - // Used only when calling this API for the Token Exchange grant type. This value - // specifies the type of token that is passed as the subject of the exchange. The - // following value is supported: - // - // * Access Token - urn:ietf:params:oauth:token-type:access_token - SubjectTokenType *string - - noSmithyDocumentSerde -} - -type CreateTokenWithIAMOutput struct { - - // A bearer token to access Amazon Web Services accounts and applications assigned - // to a user. - AccessToken *string - - // Indicates the time in seconds when an access token will expire. - ExpiresIn int32 - - // A JSON Web Token (JWT) that identifies the user associated with the issued - // access token. - IdToken *string - - // Indicates the type of tokens that are issued by IAM Identity Center. The - // following values are supported: - // - // * Access Token - urn:ietf:params:oauth:token-type:access_token - // - // * Refresh Token - urn:ietf:params:oauth:token-type:refresh_token - IssuedTokenType *string - - // A token that, if present, can be used to refresh a previously issued access - // token that might have expired. - // - // For more information about the features and limitations of the current IAM - // Identity Center OIDC implementation, see Considerations for Using this Guide in - // the [IAM Identity Center OIDC API Reference]. - // - // [IAM Identity Center OIDC API Reference]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/Welcome.html - RefreshToken *string - - // The list of scopes for which authorization is granted. The access token that is - // issued is limited to the scopes that are granted. - Scope []string - - // Used to notify the requester that the returned token is an access token. The - // supported token type is Bearer . - TokenType *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationCreateTokenWithIAMMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsRestjson1_serializeOpCreateTokenWithIAM{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsRestjson1_deserializeOpCreateTokenWithIAM{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "CreateTokenWithIAM"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addOpCreateTokenWithIAMValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateTokenWithIAM(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { - return err - } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opCreateTokenWithIAM(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "CreateTokenWithIAM", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go deleted file mode 100644 index 2022270..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go +++ /dev/null @@ -1,209 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Registers a public client with IAM Identity Center. This allows clients to -// perform authorization using the authorization code grant with Proof Key for Code -// Exchange (PKCE) or the device code grant. -func (c *Client) RegisterClient(ctx context.Context, params *RegisterClientInput, optFns ...func(*Options)) (*RegisterClientOutput, error) { - if params == nil { - params = &RegisterClientInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "RegisterClient", params, optFns, c.addOperationRegisterClientMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*RegisterClientOutput) - out.ResultMetadata = metadata - return out, nil -} - -type RegisterClientInput struct { - - // The friendly name of the client. - // - // This member is required. - ClientName *string - - // The type of client. The service supports only public as a client type. Anything - // other than public will be rejected by the service. - // - // This member is required. - ClientType *string - - // This IAM Identity Center application ARN is used to define - // administrator-managed configuration for public client access to resources. At - // authorization, the scopes, grants, and redirect URI available to this client - // will be restricted by this application resource. - EntitledApplicationArn *string - - // The list of OAuth 2.0 grant types that are defined by the client. This list is - // used to restrict the token granting flows available to the client. Supports the - // following OAuth 2.0 grant types: Authorization Code, Device Code, and Refresh - // Token. - // - // * Authorization Code - authorization_code - // - // * Device Code - urn:ietf:params:oauth:grant-type:device_code - // - // * Refresh Token - refresh_token - GrantTypes []string - - // The IAM Identity Center Issuer URL associated with an instance of IAM Identity - // Center. This value is needed for user access to resources through the client. - IssuerUrl *string - - // The list of redirect URI that are defined by the client. At completion of - // authorization, this list is used to restrict what locations the user agent can - // be redirected back to. - RedirectUris []string - - // The list of scopes that are defined by the client. Upon authorization, this - // list is used to restrict permissions when granting an access token. - Scopes []string - - noSmithyDocumentSerde -} - -type RegisterClientOutput struct { - - // An endpoint that the client can use to request authorization. - AuthorizationEndpoint *string - - // The unique identifier string for each client. This client uses this identifier - // to get authenticated by the service in subsequent calls. - ClientId *string - - // Indicates the time at which the clientId and clientSecret were issued. - ClientIdIssuedAt int64 - - // A secret string generated for the client. The client will use this string to - // get authenticated by the service in subsequent calls. - ClientSecret *string - - // Indicates the time at which the clientId and clientSecret will become invalid. - ClientSecretExpiresAt int64 - - // An endpoint that the client can use to create tokens. - TokenEndpoint *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsRestjson1_serializeOpRegisterClient{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsRestjson1_deserializeOpRegisterClient{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "RegisterClient"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addOpRegisterClientValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opRegisterClient(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { - return err - } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opRegisterClient(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "RegisterClient", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go deleted file mode 100644 index 203ca5e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go +++ /dev/null @@ -1,191 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Initiates device authorization by requesting a pair of verification codes from -// the authorization service. -func (c *Client) StartDeviceAuthorization(ctx context.Context, params *StartDeviceAuthorizationInput, optFns ...func(*Options)) (*StartDeviceAuthorizationOutput, error) { - if params == nil { - params = &StartDeviceAuthorizationInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "StartDeviceAuthorization", params, optFns, c.addOperationStartDeviceAuthorizationMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*StartDeviceAuthorizationOutput) - out.ResultMetadata = metadata - return out, nil -} - -type StartDeviceAuthorizationInput struct { - - // The unique identifier string for the client that is registered with IAM - // Identity Center. This value should come from the persisted result of the RegisterClientAPI - // operation. - // - // This member is required. - ClientId *string - - // A secret string that is generated for the client. This value should come from - // the persisted result of the RegisterClientAPI operation. - // - // This member is required. - ClientSecret *string - - // The URL for the Amazon Web Services access portal. For more information, see [Using the Amazon Web Services access portal] - // in the IAM Identity Center User Guide. - // - // [Using the Amazon Web Services access portal]: https://docs.aws.amazon.com/singlesignon/latest/userguide/using-the-portal.html - // - // This member is required. - StartUrl *string - - noSmithyDocumentSerde -} - -type StartDeviceAuthorizationOutput struct { - - // The short-lived code that is used by the device when polling for a session - // token. - DeviceCode *string - - // Indicates the number of seconds in which the verification code will become - // invalid. - ExpiresIn int32 - - // Indicates the number of seconds the client must wait between attempts when - // polling for a session. - Interval int32 - - // A one-time user verification code. This is needed to authorize an in-use device. - UserCode *string - - // The URI of the verification page that takes the userCode to authorize the - // device. - VerificationUri *string - - // An alternate URL that the client can use to automatically launch a browser. - // This process skips the manual step in which the user visits the verification - // page and enters their code. - VerificationUriComplete *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsRestjson1_serializeOpStartDeviceAuthorization{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsRestjson1_deserializeOpStartDeviceAuthorization{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "StartDeviceAuthorization"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addOpStartDeviceAuthorizationValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartDeviceAuthorization(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { - return err - } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opStartDeviceAuthorization(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "StartDeviceAuthorization", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/auth.go deleted file mode 100644 index e4b87f5..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/auth.go +++ /dev/null @@ -1,331 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - smithy "github.com/aws/smithy-go" - smithyauth "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) { - params.Region = options.Region -} - -type setLegacyContextSigningOptionsMiddleware struct { -} - -func (*setLegacyContextSigningOptionsMiddleware) ID() string { - return "setLegacyContextSigningOptions" -} - -func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - rscheme := getResolvedAuthScheme(ctx) - schemeID := rscheme.Scheme.SchemeID() - - if sn := awsmiddleware.GetSigningName(ctx); sn != "" { - if schemeID == "aws.auth#sigv4" { - smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn) - } else if schemeID == "aws.auth#sigv4a" { - smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn) - } - } - - if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" { - if schemeID == "aws.auth#sigv4" { - smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr) - } else if schemeID == "aws.auth#sigv4a" { - smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr}) - } - } - - return next.HandleFinalize(ctx, in) -} - -func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error { - return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before) -} - -type withAnonymous struct { - resolver AuthSchemeResolver -} - -var _ AuthSchemeResolver = (*withAnonymous)(nil) - -func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { - opts, err := v.resolver.ResolveAuthSchemes(ctx, params) - if err != nil { - return nil, err - } - - opts = append(opts, &smithyauth.Option{ - SchemeID: smithyauth.SchemeIDAnonymous, - }) - return opts, nil -} - -func wrapWithAnonymousAuth(options *Options) { - if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok { - return - } - - options.AuthSchemeResolver = &withAnonymous{ - resolver: options.AuthSchemeResolver, - } -} - -// AuthResolverParameters contains the set of inputs necessary for auth scheme -// resolution. -type AuthResolverParameters struct { - // The name of the operation being invoked. - Operation string - - // The region in which the operation is being invoked. - Region string -} - -func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters { - params := &AuthResolverParameters{ - Operation: operation, - } - - bindAuthParamsRegion(ctx, params, input, options) - - return params -} - -// AuthSchemeResolver returns a set of possible authentication options for an -// operation. -type AuthSchemeResolver interface { - ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error) -} - -type defaultAuthSchemeResolver struct{} - -var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil) - -func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { - if overrides, ok := operationAuthOptions[params.Operation]; ok { - return overrides(params), nil - } - return serviceAuthOptions(params), nil -} - -var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{ - "CreateToken": func(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - {SchemeID: smithyauth.SchemeIDAnonymous}, - } - }, - - "RegisterClient": func(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - {SchemeID: smithyauth.SchemeIDAnonymous}, - } - }, - - "StartDeviceAuthorization": func(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - {SchemeID: smithyauth.SchemeIDAnonymous}, - } - }, -} - -func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - { - SchemeID: smithyauth.SchemeIDSigV4, - SignerProperties: func() smithy.Properties { - var props smithy.Properties - smithyhttp.SetSigV4SigningName(&props, "sso-oauth") - smithyhttp.SetSigV4SigningRegion(&props, params.Region) - return props - }(), - }, - } -} - -type resolveAuthSchemeMiddleware struct { - operation string - options Options -} - -func (*resolveAuthSchemeMiddleware) ID() string { - return "ResolveAuthScheme" -} - -func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "ResolveAuthScheme") - defer span.End() - - params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) - options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) - if err != nil { - return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) - } - - scheme, ok := m.selectScheme(options) - if !ok { - return out, metadata, fmt.Errorf("could not select an auth scheme") - } - - ctx = setResolvedAuthScheme(ctx, scheme) - - span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID()) - span.End() - return next.HandleFinalize(ctx, in) -} - -func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - for _, option := range options { - if option.SchemeID == smithyauth.SchemeIDAnonymous { - return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true - } - - for _, scheme := range m.options.AuthSchemes { - if scheme.SchemeID() != option.SchemeID { - continue - } - - if scheme.IdentityResolver(m.options) != nil { - return newResolvedAuthScheme(scheme, option), true - } - } - } - - return nil, false -} - -type resolvedAuthSchemeKey struct{} - -type resolvedAuthScheme struct { - Scheme smithyhttp.AuthScheme - IdentityProperties smithy.Properties - SignerProperties smithy.Properties -} - -func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme { - return &resolvedAuthScheme{ - Scheme: scheme, - IdentityProperties: option.IdentityProperties, - SignerProperties: option.SignerProperties, - } -} - -func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context { - return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme) -} - -func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme { - v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme) - return v -} - -type getIdentityMiddleware struct { - options Options -} - -func (*getIdentityMiddleware) ID() string { - return "GetIdentity" -} - -func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - innerCtx, span := tracing.StartSpan(ctx, "GetIdentity") - defer span.End() - - rscheme := getResolvedAuthScheme(innerCtx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - resolver := rscheme.Scheme.IdentityResolver(m.options) - if resolver == nil { - return out, metadata, fmt.Errorf("no identity resolver") - } - - identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration", - func() (smithyauth.Identity, error) { - return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties) - }, - func(o *metrics.RecordMetricOptions) { - o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) - }) - if err != nil { - return out, metadata, fmt.Errorf("get identity: %w", err) - } - - ctx = setIdentity(ctx, identity) - - span.End() - return next.HandleFinalize(ctx, in) -} - -type identityKey struct{} - -func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context { - return middleware.WithStackValue(ctx, identityKey{}, identity) -} - -func getIdentity(ctx context.Context) smithyauth.Identity { - v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity) - return v -} - -type signRequestMiddleware struct { - options Options -} - -func (*signRequestMiddleware) ID() string { - return "Signing" -} - -func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "SignRequest") - defer span.End() - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request) - } - - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - identity := getIdentity(ctx) - if identity == nil { - return out, metadata, fmt.Errorf("no identity") - } - - signer := rscheme.Scheme.Signer() - if signer == nil { - return out, metadata, fmt.Errorf("no signer") - } - - _, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) { - return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties) - }, func(o *metrics.RecordMetricOptions) { - o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) - }) - if err != nil { - return out, metadata, fmt.Errorf("sign request: %w", err) - } - - span.End() - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go deleted file mode 100644 index ae9f145..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go +++ /dev/null @@ -1,2188 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws/protocol/restjson" - "github.com/aws/aws-sdk-go-v2/service/ssooidc/types" - smithy "github.com/aws/smithy-go" - smithyio "github.com/aws/smithy-go/io" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/ptr" - smithytime "github.com/aws/smithy-go/time" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "io" - "strings" - "time" -) - -func deserializeS3Expires(v string) (*time.Time, error) { - t, err := smithytime.ParseHTTPDate(v) - if err != nil { - return nil, nil - } - return &t, nil -} - -type awsRestjson1_deserializeOpCreateToken struct { -} - -func (*awsRestjson1_deserializeOpCreateToken) ID() string { - return "OperationDeserializer" -} - -func (m *awsRestjson1_deserializeOpCreateToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorCreateToken(response, &metadata) - } - output := &CreateTokenOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsRestjson1_deserializeOpDocumentCreateTokenOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - span.End() - return out, metadata, err -} - -func awsRestjson1_deserializeOpErrorCreateToken(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AccessDeniedException", errorCode): - return awsRestjson1_deserializeErrorAccessDeniedException(response, errorBody) - - case strings.EqualFold("AuthorizationPendingException", errorCode): - return awsRestjson1_deserializeErrorAuthorizationPendingException(response, errorBody) - - case strings.EqualFold("ExpiredTokenException", errorCode): - return awsRestjson1_deserializeErrorExpiredTokenException(response, errorBody) - - case strings.EqualFold("InternalServerException", errorCode): - return awsRestjson1_deserializeErrorInternalServerException(response, errorBody) - - case strings.EqualFold("InvalidClientException", errorCode): - return awsRestjson1_deserializeErrorInvalidClientException(response, errorBody) - - case strings.EqualFold("InvalidGrantException", errorCode): - return awsRestjson1_deserializeErrorInvalidGrantException(response, errorBody) - - case strings.EqualFold("InvalidRequestException", errorCode): - return awsRestjson1_deserializeErrorInvalidRequestException(response, errorBody) - - case strings.EqualFold("InvalidScopeException", errorCode): - return awsRestjson1_deserializeErrorInvalidScopeException(response, errorBody) - - case strings.EqualFold("SlowDownException", errorCode): - return awsRestjson1_deserializeErrorSlowDownException(response, errorBody) - - case strings.EqualFold("UnauthorizedClientException", errorCode): - return awsRestjson1_deserializeErrorUnauthorizedClientException(response, errorBody) - - case strings.EqualFold("UnsupportedGrantTypeException", errorCode): - return awsRestjson1_deserializeErrorUnsupportedGrantTypeException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsRestjson1_deserializeOpDocumentCreateTokenOutput(v **CreateTokenOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateTokenOutput - if *v == nil { - sv = &CreateTokenOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "accessToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AccessToken to be of type string, got %T instead", value) - } - sv.AccessToken = ptr.String(jtv) - } - - case "expiresIn": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ExpirationInSeconds to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ExpiresIn = int32(i64) - } - - case "idToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected IdToken to be of type string, got %T instead", value) - } - sv.IdToken = ptr.String(jtv) - } - - case "refreshToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected RefreshToken to be of type string, got %T instead", value) - } - sv.RefreshToken = ptr.String(jtv) - } - - case "tokenType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TokenType to be of type string, got %T instead", value) - } - sv.TokenType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -type awsRestjson1_deserializeOpCreateTokenWithIAM struct { -} - -func (*awsRestjson1_deserializeOpCreateTokenWithIAM) ID() string { - return "OperationDeserializer" -} - -func (m *awsRestjson1_deserializeOpCreateTokenWithIAM) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorCreateTokenWithIAM(response, &metadata) - } - output := &CreateTokenWithIAMOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsRestjson1_deserializeOpDocumentCreateTokenWithIAMOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - span.End() - return out, metadata, err -} - -func awsRestjson1_deserializeOpErrorCreateTokenWithIAM(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("AccessDeniedException", errorCode): - return awsRestjson1_deserializeErrorAccessDeniedException(response, errorBody) - - case strings.EqualFold("AuthorizationPendingException", errorCode): - return awsRestjson1_deserializeErrorAuthorizationPendingException(response, errorBody) - - case strings.EqualFold("ExpiredTokenException", errorCode): - return awsRestjson1_deserializeErrorExpiredTokenException(response, errorBody) - - case strings.EqualFold("InternalServerException", errorCode): - return awsRestjson1_deserializeErrorInternalServerException(response, errorBody) - - case strings.EqualFold("InvalidClientException", errorCode): - return awsRestjson1_deserializeErrorInvalidClientException(response, errorBody) - - case strings.EqualFold("InvalidGrantException", errorCode): - return awsRestjson1_deserializeErrorInvalidGrantException(response, errorBody) - - case strings.EqualFold("InvalidRequestException", errorCode): - return awsRestjson1_deserializeErrorInvalidRequestException(response, errorBody) - - case strings.EqualFold("InvalidRequestRegionException", errorCode): - return awsRestjson1_deserializeErrorInvalidRequestRegionException(response, errorBody) - - case strings.EqualFold("InvalidScopeException", errorCode): - return awsRestjson1_deserializeErrorInvalidScopeException(response, errorBody) - - case strings.EqualFold("SlowDownException", errorCode): - return awsRestjson1_deserializeErrorSlowDownException(response, errorBody) - - case strings.EqualFold("UnauthorizedClientException", errorCode): - return awsRestjson1_deserializeErrorUnauthorizedClientException(response, errorBody) - - case strings.EqualFold("UnsupportedGrantTypeException", errorCode): - return awsRestjson1_deserializeErrorUnsupportedGrantTypeException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsRestjson1_deserializeOpDocumentCreateTokenWithIAMOutput(v **CreateTokenWithIAMOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *CreateTokenWithIAMOutput - if *v == nil { - sv = &CreateTokenWithIAMOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "accessToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected AccessToken to be of type string, got %T instead", value) - } - sv.AccessToken = ptr.String(jtv) - } - - case "expiresIn": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ExpirationInSeconds to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ExpiresIn = int32(i64) - } - - case "idToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected IdToken to be of type string, got %T instead", value) - } - sv.IdToken = ptr.String(jtv) - } - - case "issuedTokenType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TokenTypeURI to be of type string, got %T instead", value) - } - sv.IssuedTokenType = ptr.String(jtv) - } - - case "refreshToken": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected RefreshToken to be of type string, got %T instead", value) - } - sv.RefreshToken = ptr.String(jtv) - } - - case "scope": - if err := awsRestjson1_deserializeDocumentScopes(&sv.Scope, value); err != nil { - return err - } - - case "tokenType": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TokenType to be of type string, got %T instead", value) - } - sv.TokenType = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -type awsRestjson1_deserializeOpRegisterClient struct { -} - -func (*awsRestjson1_deserializeOpRegisterClient) ID() string { - return "OperationDeserializer" -} - -func (m *awsRestjson1_deserializeOpRegisterClient) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorRegisterClient(response, &metadata) - } - output := &RegisterClientOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsRestjson1_deserializeOpDocumentRegisterClientOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - span.End() - return out, metadata, err -} - -func awsRestjson1_deserializeOpErrorRegisterClient(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerException", errorCode): - return awsRestjson1_deserializeErrorInternalServerException(response, errorBody) - - case strings.EqualFold("InvalidClientMetadataException", errorCode): - return awsRestjson1_deserializeErrorInvalidClientMetadataException(response, errorBody) - - case strings.EqualFold("InvalidRedirectUriException", errorCode): - return awsRestjson1_deserializeErrorInvalidRedirectUriException(response, errorBody) - - case strings.EqualFold("InvalidRequestException", errorCode): - return awsRestjson1_deserializeErrorInvalidRequestException(response, errorBody) - - case strings.EqualFold("InvalidScopeException", errorCode): - return awsRestjson1_deserializeErrorInvalidScopeException(response, errorBody) - - case strings.EqualFold("UnsupportedGrantTypeException", errorCode): - return awsRestjson1_deserializeErrorUnsupportedGrantTypeException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsRestjson1_deserializeOpDocumentRegisterClientOutput(v **RegisterClientOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *RegisterClientOutput - if *v == nil { - sv = &RegisterClientOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "authorizationEndpoint": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected URI to be of type string, got %T instead", value) - } - sv.AuthorizationEndpoint = ptr.String(jtv) - } - - case "clientId": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ClientId to be of type string, got %T instead", value) - } - sv.ClientId = ptr.String(jtv) - } - - case "clientIdIssuedAt": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected LongTimeStampType to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ClientIdIssuedAt = i64 - } - - case "clientSecret": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ClientSecret to be of type string, got %T instead", value) - } - sv.ClientSecret = ptr.String(jtv) - } - - case "clientSecretExpiresAt": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected LongTimeStampType to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ClientSecretExpiresAt = i64 - } - - case "tokenEndpoint": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected URI to be of type string, got %T instead", value) - } - sv.TokenEndpoint = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -type awsRestjson1_deserializeOpStartDeviceAuthorization struct { -} - -func (*awsRestjson1_deserializeOpStartDeviceAuthorization) ID() string { - return "OperationDeserializer" -} - -func (m *awsRestjson1_deserializeOpStartDeviceAuthorization) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsRestjson1_deserializeOpErrorStartDeviceAuthorization(response, &metadata) - } - output := &StartDeviceAuthorizationOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(response.Body, ringBuffer) - - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - err = awsRestjson1_deserializeOpDocumentStartDeviceAuthorizationOutput(&output, shape) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - span.End() - return out, metadata, err -} - -func awsRestjson1_deserializeOpErrorStartDeviceAuthorization(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) - } - if len(message) != 0 { - errorMessage = message - } - - switch { - case strings.EqualFold("InternalServerException", errorCode): - return awsRestjson1_deserializeErrorInternalServerException(response, errorBody) - - case strings.EqualFold("InvalidClientException", errorCode): - return awsRestjson1_deserializeErrorInvalidClientException(response, errorBody) - - case strings.EqualFold("InvalidRequestException", errorCode): - return awsRestjson1_deserializeErrorInvalidRequestException(response, errorBody) - - case strings.EqualFold("SlowDownException", errorCode): - return awsRestjson1_deserializeErrorSlowDownException(response, errorBody) - - case strings.EqualFold("UnauthorizedClientException", errorCode): - return awsRestjson1_deserializeErrorUnauthorizedClientException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsRestjson1_deserializeOpDocumentStartDeviceAuthorizationOutput(v **StartDeviceAuthorizationOutput, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *StartDeviceAuthorizationOutput - if *v == nil { - sv = &StartDeviceAuthorizationOutput{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "deviceCode": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected DeviceCode to be of type string, got %T instead", value) - } - sv.DeviceCode = ptr.String(jtv) - } - - case "expiresIn": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected ExpirationInSeconds to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.ExpiresIn = int32(i64) - } - - case "interval": - if value != nil { - jtv, ok := value.(json.Number) - if !ok { - return fmt.Errorf("expected IntervalInSeconds to be json.Number, got %T instead", value) - } - i64, err := jtv.Int64() - if err != nil { - return err - } - sv.Interval = int32(i64) - } - - case "userCode": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected UserCode to be of type string, got %T instead", value) - } - sv.UserCode = ptr.String(jtv) - } - - case "verificationUri": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected URI to be of type string, got %T instead", value) - } - sv.VerificationUri = ptr.String(jtv) - } - - case "verificationUriComplete": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected URI to be of type string, got %T instead", value) - } - sv.VerificationUriComplete = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeErrorAccessDeniedException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.AccessDeniedException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentAccessDeniedException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorAuthorizationPendingException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.AuthorizationPendingException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentAuthorizationPendingException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorExpiredTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.ExpiredTokenException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentExpiredTokenException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorInternalServerException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InternalServerException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentInternalServerException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorInvalidClientException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidClientException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentInvalidClientException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorInvalidClientMetadataException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidClientMetadataException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentInvalidClientMetadataException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorInvalidGrantException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidGrantException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentInvalidGrantException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorInvalidRedirectUriException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidRedirectUriException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentInvalidRedirectUriException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorInvalidRequestException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidRequestException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentInvalidRequestException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorInvalidRequestRegionException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidRequestRegionException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentInvalidRequestRegionException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorInvalidScopeException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidScopeException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentInvalidScopeException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorSlowDownException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.SlowDownException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentSlowDownException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorUnauthorizedClientException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.UnauthorizedClientException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentUnauthorizedClientException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeErrorUnsupportedGrantTypeException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.UnsupportedGrantTypeException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - - body := io.TeeReader(errorBody, ringBuffer) - decoder := json.NewDecoder(body) - decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - err := awsRestjson1_deserializeDocumentUnsupportedGrantTypeException(&output, shape) - - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return err - } - - errorBody.Seek(0, io.SeekStart) - - return output -} - -func awsRestjson1_deserializeDocumentAccessDeniedException(v **types.AccessDeniedException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AccessDeniedException - if *v == nil { - sv = &types.AccessDeniedException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentAuthorizationPendingException(v **types.AuthorizationPendingException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.AuthorizationPendingException - if *v == nil { - sv = &types.AuthorizationPendingException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentExpiredTokenException(v **types.ExpiredTokenException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.ExpiredTokenException - if *v == nil { - sv = &types.ExpiredTokenException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentInternalServerException(v **types.InternalServerException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InternalServerException - if *v == nil { - sv = &types.InternalServerException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentInvalidClientException(v **types.InvalidClientException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidClientException - if *v == nil { - sv = &types.InvalidClientException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentInvalidClientMetadataException(v **types.InvalidClientMetadataException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidClientMetadataException - if *v == nil { - sv = &types.InvalidClientMetadataException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentInvalidGrantException(v **types.InvalidGrantException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidGrantException - if *v == nil { - sv = &types.InvalidGrantException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentInvalidRedirectUriException(v **types.InvalidRedirectUriException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidRedirectUriException - if *v == nil { - sv = &types.InvalidRedirectUriException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentInvalidRequestException(v **types.InvalidRequestException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidRequestException - if *v == nil { - sv = &types.InvalidRequestException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentInvalidRequestRegionException(v **types.InvalidRequestRegionException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidRequestRegionException - if *v == nil { - sv = &types.InvalidRequestRegionException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "endpoint": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Location to be of type string, got %T instead", value) - } - sv.Endpoint = ptr.String(jtv) - } - - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - case "region": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Region to be of type string, got %T instead", value) - } - sv.Region = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentInvalidScopeException(v **types.InvalidScopeException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.InvalidScopeException - if *v == nil { - sv = &types.InvalidScopeException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentScopes(v *[]string, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.([]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var cv []string - if *v == nil { - cv = []string{} - } else { - cv = *v - } - - for _, value := range shape { - var col string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Scope to be of type string, got %T instead", value) - } - col = jtv - } - cv = append(cv, col) - - } - *v = cv - return nil -} - -func awsRestjson1_deserializeDocumentSlowDownException(v **types.SlowDownException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.SlowDownException - if *v == nil { - sv = &types.SlowDownException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentUnauthorizedClientException(v **types.UnauthorizedClientException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnauthorizedClientException - if *v == nil { - sv = &types.UnauthorizedClientException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} - -func awsRestjson1_deserializeDocumentUnsupportedGrantTypeException(v **types.UnsupportedGrantTypeException, value interface{}) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - if value == nil { - return nil - } - - shape, ok := value.(map[string]interface{}) - if !ok { - return fmt.Errorf("unexpected JSON type %v", value) - } - - var sv *types.UnsupportedGrantTypeException - if *v == nil { - sv = &types.UnsupportedGrantTypeException{} - } else { - sv = *v - } - - for key, value := range shape { - switch key { - case "error": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected Error to be of type string, got %T instead", value) - } - sv.Error_ = ptr.String(jtv) - } - - case "error_description": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected ErrorDescription to be of type string, got %T instead", value) - } - sv.Error_description = ptr.String(jtv) - } - - default: - _, _ = key, value - - } - } - *v = sv - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/doc.go deleted file mode 100644 index f3510b1..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/doc.go +++ /dev/null @@ -1,49 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -// Package ssooidc provides the API client, operations, and parameter types for -// AWS SSO OIDC. -// -// IAM Identity Center OpenID Connect (OIDC) is a web service that enables a -// client (such as CLI or a native application) to register with IAM Identity -// Center. The service also enables the client to fetch the user’s access token -// upon successful authentication and authorization with IAM Identity Center. -// -// # API namespaces -// -// IAM Identity Center uses the sso and identitystore API namespaces. IAM Identity -// Center OpenID Connect uses the sso-oidc namespace. -// -// # Considerations for using this guide -// -// Before you begin using this guide, we recommend that you first review the -// following important information about how the IAM Identity Center OIDC service -// works. -// -// - The IAM Identity Center OIDC service currently implements only the portions -// of the OAuth 2.0 Device Authorization Grant standard ([https://tools.ietf.org/html/rfc8628] ) that are necessary to -// enable single sign-on authentication with the CLI. -// -// - With older versions of the CLI, the service only emits OIDC access tokens, -// so to obtain a new token, users must explicitly re-authenticate. To access the -// OIDC flow that supports token refresh and doesn’t require re-authentication, -// update to the latest CLI version (1.27.10 for CLI V1 and 2.9.0 for CLI V2) with -// support for OIDC token refresh and configurable IAM Identity Center session -// durations. For more information, see [Configure Amazon Web Services access portal session duration]. -// -// - The access tokens provided by this service grant access to all Amazon Web -// Services account entitlements assigned to an IAM Identity Center user, not just -// a particular application. -// -// - The documentation in this guide does not describe the mechanism to convert -// the access token into Amazon Web Services Auth (“sigv4”) credentials for use -// with IAM-protected Amazon Web Services service endpoints. For more information, -// see [GetRoleCredentials]in the IAM Identity Center Portal API Reference Guide. -// -// For general information about IAM Identity Center, see [What is IAM Identity Center?] in the IAM Identity -// Center User Guide. -// -// [Configure Amazon Web Services access portal session duration]: https://docs.aws.amazon.com/singlesignon/latest/userguide/configure-user-session.html -// [GetRoleCredentials]: https://docs.aws.amazon.com/singlesignon/latest/PortalAPIReference/API_GetRoleCredentials.html -// [https://tools.ietf.org/html/rfc8628]: https://tools.ietf.org/html/rfc8628 -// [What is IAM Identity Center?]: https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html -package ssooidc diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/endpoints.go deleted file mode 100644 index 6feea0c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/endpoints.go +++ /dev/null @@ -1,556 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "context" - "errors" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" - "github.com/aws/aws-sdk-go-v2/internal/endpoints" - "github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn" - internalendpoints "github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints" - smithyauth "github.com/aws/smithy-go/auth" - smithyendpoints "github.com/aws/smithy-go/endpoints" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/ptr" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net/http" - "net/url" - "os" - "strings" -) - -// EndpointResolverOptions is the service endpoint resolver options -type EndpointResolverOptions = internalendpoints.Options - -// EndpointResolver interface for resolving service endpoints. -type EndpointResolver interface { - ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error) -} - -var _ EndpointResolver = &internalendpoints.Resolver{} - -// NewDefaultEndpointResolver constructs a new service endpoint resolver -func NewDefaultEndpointResolver() *internalendpoints.Resolver { - return internalendpoints.New() -} - -// EndpointResolverFunc is a helper utility that wraps a function so it satisfies -// the EndpointResolver interface. This is useful when you want to add additional -// endpoint resolving logic, or stub out specific endpoints with custom values. -type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error) - -func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - return fn(region, options) -} - -// EndpointResolverFromURL returns an EndpointResolver configured using the -// provided endpoint url. By default, the resolved endpoint resolver uses the -// client region as signing region, and the endpoint source is set to -// EndpointSourceCustom.You can provide functional options to configure endpoint -// values for the resolved endpoint. -func EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver { - e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom} - for _, fn := range optFns { - fn(&e) - } - - return EndpointResolverFunc( - func(region string, options EndpointResolverOptions) (aws.Endpoint, error) { - if len(e.SigningRegion) == 0 { - e.SigningRegion = region - } - return e, nil - }, - ) -} - -type ResolveEndpoint struct { - Resolver EndpointResolver - Options EndpointResolverOptions -} - -func (*ResolveEndpoint) ID() string { - return "ResolveEndpoint" -} - -func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { - return next.HandleSerialize(ctx, in) - } - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.Resolver == nil { - return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") - } - - eo := m.Options - eo.Logger = middleware.GetLogger(ctx) - - var endpoint aws.Endpoint - endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo) - if err != nil { - nf := (&aws.EndpointNotFoundError{}) - if errors.As(err, &nf) { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false) - return next.HandleSerialize(ctx, in) - } - return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) - } - - req.URL, err = url.Parse(endpoint.URL) - if err != nil { - return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err) - } - - if len(awsmiddleware.GetSigningName(ctx)) == 0 { - signingName := endpoint.SigningName - if len(signingName) == 0 { - signingName = "sso-oauth" - } - ctx = awsmiddleware.SetSigningName(ctx, signingName) - } - ctx = awsmiddleware.SetEndpointSource(ctx, endpoint.Source) - ctx = smithyhttp.SetHostnameImmutable(ctx, endpoint.HostnameImmutable) - ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion) - ctx = awsmiddleware.SetPartitionID(ctx, endpoint.PartitionID) - return next.HandleSerialize(ctx, in) -} -func addResolveEndpointMiddleware(stack *middleware.Stack, o Options) error { - return stack.Serialize.Insert(&ResolveEndpoint{ - Resolver: o.EndpointResolver, - Options: o.EndpointOptions, - }, "OperationSerializer", middleware.Before) -} - -func removeResolveEndpointMiddleware(stack *middleware.Stack) error { - _, err := stack.Serialize.Remove((&ResolveEndpoint{}).ID()) - return err -} - -type wrappedEndpointResolver struct { - awsResolver aws.EndpointResolverWithOptions -} - -func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - return w.awsResolver.ResolveEndpoint(ServiceID, region, options) -} - -type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) - -func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) { - return a(service, region) -} - -var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) - -// withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error, -// and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked -// via its middleware. -// -// If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated. -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver { - var resolver aws.EndpointResolverWithOptions - - if awsResolverWithOptions != nil { - resolver = awsResolverWithOptions - } else if awsResolver != nil { - resolver = awsEndpointResolverAdaptor(awsResolver.ResolveEndpoint) - } - - return &wrappedEndpointResolver{ - awsResolver: resolver, - } -} - -func finalizeClientEndpointResolverOptions(options *Options) { - options.EndpointOptions.LogDeprecated = options.ClientLogMode.IsDeprecatedUsage() - - if len(options.EndpointOptions.ResolvedRegion) == 0 { - const fipsInfix = "-fips-" - const fipsPrefix = "fips-" - const fipsSuffix = "-fips" - - if strings.Contains(options.Region, fipsInfix) || - strings.Contains(options.Region, fipsPrefix) || - strings.Contains(options.Region, fipsSuffix) { - options.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( - options.Region, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") - options.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled - } - } - -} - -func resolveEndpointResolverV2(options *Options) { - if options.EndpointResolverV2 == nil { - options.EndpointResolverV2 = NewDefaultEndpointResolverV2() - } -} - -func resolveBaseEndpoint(cfg aws.Config, o *Options) { - if cfg.BaseEndpoint != nil { - o.BaseEndpoint = cfg.BaseEndpoint - } - - _, g := os.LookupEnv("AWS_ENDPOINT_URL") - _, s := os.LookupEnv("AWS_ENDPOINT_URL_SSO_OIDC") - - if g && !s { - return - } - - value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "SSO OIDC", cfg.ConfigSources) - if found && err == nil { - o.BaseEndpoint = &value - } -} - -func bindRegion(region string) *string { - if region == "" { - return nil - } - return aws.String(endpoints.MapFIPSRegion(region)) -} - -// EndpointParameters provides the parameters that influence how endpoints are -// resolved. -type EndpointParameters struct { - // The AWS region used to dispatch the request. - // - // Parameter is - // required. - // - // AWS::Region - Region *string - - // When true, use the dual-stack endpoint. If the configured endpoint does not - // support dual-stack, dispatching the request MAY return an error. - // - // Defaults to - // false if no value is provided. - // - // AWS::UseDualStack - UseDualStack *bool - - // When true, send this request to the FIPS-compliant regional endpoint. If the - // configured endpoint does not have a FIPS compliant endpoint, dispatching the - // request will return an error. - // - // Defaults to false if no value is - // provided. - // - // AWS::UseFIPS - UseFIPS *bool - - // Override the endpoint used to send this request - // - // Parameter is - // required. - // - // SDK::Endpoint - Endpoint *string -} - -// ValidateRequired validates required parameters are set. -func (p EndpointParameters) ValidateRequired() error { - if p.UseDualStack == nil { - return fmt.Errorf("parameter UseDualStack is required") - } - - if p.UseFIPS == nil { - return fmt.Errorf("parameter UseFIPS is required") - } - - return nil -} - -// WithDefaults returns a shallow copy of EndpointParameterswith default values -// applied to members where applicable. -func (p EndpointParameters) WithDefaults() EndpointParameters { - if p.UseDualStack == nil { - p.UseDualStack = ptr.Bool(false) - } - - if p.UseFIPS == nil { - p.UseFIPS = ptr.Bool(false) - } - return p -} - -type stringSlice []string - -func (s stringSlice) Get(i int) *string { - if i < 0 || i >= len(s) { - return nil - } - - v := s[i] - return &v -} - -// EndpointResolverV2 provides the interface for resolving service endpoints. -type EndpointResolverV2 interface { - // ResolveEndpoint attempts to resolve the endpoint with the provided options, - // returning the endpoint if found. Otherwise an error is returned. - ResolveEndpoint(ctx context.Context, params EndpointParameters) ( - smithyendpoints.Endpoint, error, - ) -} - -// resolver provides the implementation for resolving endpoints. -type resolver struct{} - -func NewDefaultEndpointResolverV2() EndpointResolverV2 { - return &resolver{} -} - -// ResolveEndpoint attempts to resolve the endpoint with the provided options, -// returning the endpoint if found. Otherwise an error is returned. -func (r *resolver) ResolveEndpoint( - ctx context.Context, params EndpointParameters, -) ( - endpoint smithyendpoints.Endpoint, err error, -) { - params = params.WithDefaults() - if err = params.ValidateRequired(); err != nil { - return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) - } - _UseDualStack := *params.UseDualStack - _UseFIPS := *params.UseFIPS - - if exprVal := params.Endpoint; exprVal != nil { - _Endpoint := *exprVal - _ = _Endpoint - if _UseFIPS == true { - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported") - } - if _UseDualStack == true { - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported") - } - uriString := _Endpoint - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - if exprVal := params.Region; exprVal != nil { - _Region := *exprVal - _ = _Region - if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { - _PartitionResult := *exprVal - _ = _PartitionResult - if _UseFIPS == true { - if _UseDualStack == true { - if true == _PartitionResult.SupportsFIPS { - if true == _PartitionResult.SupportsDualStack { - uriString := func() string { - var out strings.Builder - out.WriteString("https://oidc-fips.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DualStackDnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") - } - } - if _UseFIPS == true { - if _PartitionResult.SupportsFIPS == true { - if _PartitionResult.Name == "aws-us-gov" { - uriString := func() string { - var out strings.Builder - out.WriteString("https://oidc.") - out.WriteString(_Region) - out.WriteString(".amazonaws.com") - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - uriString := func() string { - var out strings.Builder - out.WriteString("https://oidc-fips.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS") - } - if _UseDualStack == true { - if true == _PartitionResult.SupportsDualStack { - uriString := func() string { - var out strings.Builder - out.WriteString("https://oidc.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DualStackDnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack") - } - uriString := func() string { - var out strings.Builder - out.WriteString("https://oidc.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region") -} - -type endpointParamsBinder interface { - bindEndpointParams(*EndpointParameters) -} - -func bindEndpointParams(ctx context.Context, input interface{}, options Options) *EndpointParameters { - params := &EndpointParameters{} - - params.Region = bindRegion(options.Region) - params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) - params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) - params.Endpoint = options.BaseEndpoint - - if b, ok := input.(endpointParamsBinder); ok { - b.bindEndpointParams(params) - } - - return params -} - -type resolveEndpointV2Middleware struct { - options Options -} - -func (*resolveEndpointV2Middleware) ID() string { - return "ResolveEndpointV2" -} - -func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "ResolveEndpoint") - defer span.End() - - if awsmiddleware.GetRequiresLegacyEndpoints(ctx) { - return next.HandleFinalize(ctx, in) - } - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.options.EndpointResolverV2 == nil { - return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") - } - - params := bindEndpointParams(ctx, getOperationInput(ctx), m.options) - endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration", - func() (smithyendpoints.Endpoint, error) { - return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) - }) - if err != nil { - return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) - } - - span.SetProperty("client.call.resolved_endpoint", endpt.URI.String()) - - if endpt.URI.RawPath == "" && req.URL.RawPath != "" { - endpt.URI.RawPath = endpt.URI.Path - } - req.URL.Scheme = endpt.URI.Scheme - req.URL.Host = endpt.URI.Host - req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path) - req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath) - for k := range endpt.Headers { - req.Header.Set(k, endpt.Headers.Get(k)) - } - - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - opts, _ := smithyauth.GetAuthOptions(&endpt.Properties) - for _, o := range opts { - rscheme.SignerProperties.SetAll(&o.SignerProperties) - } - - span.End() - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json deleted file mode 100644 index b2a5263..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "dependencies": { - "github.com/aws/aws-sdk-go-v2": "v1.4.0", - "github.com/aws/aws-sdk-go-v2/internal/configsources": "v0.0.0-00010101000000-000000000000", - "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2": "v2.0.0-00010101000000-000000000000", - "github.com/aws/smithy-go": "v1.4.0" - }, - "files": [ - "api_client.go", - "api_client_test.go", - "api_op_CreateToken.go", - "api_op_CreateTokenWithIAM.go", - "api_op_RegisterClient.go", - "api_op_StartDeviceAuthorization.go", - "auth.go", - "deserializers.go", - "doc.go", - "endpoints.go", - "endpoints_config_test.go", - "endpoints_test.go", - "generated.json", - "internal/endpoints/endpoints.go", - "internal/endpoints/endpoints_test.go", - "options.go", - "protocol_test.go", - "serializers.go", - "snapshot_test.go", - "types/errors.go", - "types/types.go", - "validators.go" - ], - "go": "1.15", - "module": "github.com/aws/aws-sdk-go-v2/service/ssooidc", - "unstable": false -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go deleted file mode 100644 index b338cba..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package ssooidc - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.28.13" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints/endpoints.go deleted file mode 100644 index b4c61eb..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints/endpoints.go +++ /dev/null @@ -1,566 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package endpoints - -import ( - "github.com/aws/aws-sdk-go-v2/aws" - endpoints "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2" - "github.com/aws/smithy-go/logging" - "regexp" -) - -// Options is the endpoint resolver configuration options -type Options struct { - // Logger is a logging implementation that log events should be sent to. - Logger logging.Logger - - // LogDeprecated indicates that deprecated endpoints should be logged to the - // provided logger. - LogDeprecated bool - - // ResolvedRegion is used to override the region to be resolved, rather then the - // using the value passed to the ResolveEndpoint method. This value is used by the - // SDK to translate regions like fips-us-east-1 or us-east-1-fips to an alternative - // name. You must not set this value directly in your application. - ResolvedRegion string - - // DisableHTTPS informs the resolver to return an endpoint that does not use the - // HTTPS scheme. - DisableHTTPS bool - - // UseDualStackEndpoint specifies the resolver must resolve a dual-stack endpoint. - UseDualStackEndpoint aws.DualStackEndpointState - - // UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint. - UseFIPSEndpoint aws.FIPSEndpointState -} - -func (o Options) GetResolvedRegion() string { - return o.ResolvedRegion -} - -func (o Options) GetDisableHTTPS() bool { - return o.DisableHTTPS -} - -func (o Options) GetUseDualStackEndpoint() aws.DualStackEndpointState { - return o.UseDualStackEndpoint -} - -func (o Options) GetUseFIPSEndpoint() aws.FIPSEndpointState { - return o.UseFIPSEndpoint -} - -func transformToSharedOptions(options Options) endpoints.Options { - return endpoints.Options{ - Logger: options.Logger, - LogDeprecated: options.LogDeprecated, - ResolvedRegion: options.ResolvedRegion, - DisableHTTPS: options.DisableHTTPS, - UseDualStackEndpoint: options.UseDualStackEndpoint, - UseFIPSEndpoint: options.UseFIPSEndpoint, - } -} - -// Resolver SSO OIDC endpoint resolver -type Resolver struct { - partitions endpoints.Partitions -} - -// ResolveEndpoint resolves the service endpoint for the given region and options -func (r *Resolver) ResolveEndpoint(region string, options Options) (endpoint aws.Endpoint, err error) { - if len(region) == 0 { - return endpoint, &aws.MissingRegionError{} - } - - opt := transformToSharedOptions(options) - return r.partitions.ResolveEndpoint(region, opt) -} - -// New returns a new Resolver -func New() *Resolver { - return &Resolver{ - partitions: defaultPartitions, - } -} - -var partitionRegexp = struct { - Aws *regexp.Regexp - AwsCn *regexp.Regexp - AwsIso *regexp.Regexp - AwsIsoB *regexp.Regexp - AwsIsoE *regexp.Regexp - AwsIsoF *regexp.Regexp - AwsUsGov *regexp.Regexp -}{ - - Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"), - AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), - AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), - AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), - AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), - AwsIsoF: regexp.MustCompile("^us\\-isof\\-\\w+\\-\\d+$"), - AwsUsGov: regexp.MustCompile("^us\\-gov\\-\\w+\\-\\d+$"), -} - -var defaultPartitions = endpoints.Partitions{ - { - ID: "aws", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "oidc.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "oidc-fips.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "oidc-fips.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "oidc.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.Aws, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "af-south-1", - }: endpoints.Endpoint{ - Hostname: "oidc.af-south-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "af-south-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-east-1", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-east-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-northeast-1", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-northeast-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-northeast-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-northeast-2", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-northeast-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-northeast-2", - }, - }, - endpoints.EndpointKey{ - Region: "ap-northeast-3", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-northeast-3.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-northeast-3", - }, - }, - endpoints.EndpointKey{ - Region: "ap-south-1", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-south-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-south-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-south-2", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-south-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-south-2", - }, - }, - endpoints.EndpointKey{ - Region: "ap-southeast-1", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-southeast-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-southeast-1", - }, - }, - endpoints.EndpointKey{ - Region: "ap-southeast-2", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-southeast-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-southeast-2", - }, - }, - endpoints.EndpointKey{ - Region: "ap-southeast-3", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-southeast-3.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-southeast-3", - }, - }, - endpoints.EndpointKey{ - Region: "ap-southeast-4", - }: endpoints.Endpoint{ - Hostname: "oidc.ap-southeast-4.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ap-southeast-4", - }, - }, - endpoints.EndpointKey{ - Region: "ca-central-1", - }: endpoints.Endpoint{ - Hostname: "oidc.ca-central-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ca-central-1", - }, - }, - endpoints.EndpointKey{ - Region: "ca-west-1", - }: endpoints.Endpoint{ - Hostname: "oidc.ca-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "ca-west-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-central-1", - }: endpoints.Endpoint{ - Hostname: "oidc.eu-central-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-central-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-central-2", - }: endpoints.Endpoint{ - Hostname: "oidc.eu-central-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-central-2", - }, - }, - endpoints.EndpointKey{ - Region: "eu-north-1", - }: endpoints.Endpoint{ - Hostname: "oidc.eu-north-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-north-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-south-1", - }: endpoints.Endpoint{ - Hostname: "oidc.eu-south-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-south-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-south-2", - }: endpoints.Endpoint{ - Hostname: "oidc.eu-south-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-south-2", - }, - }, - endpoints.EndpointKey{ - Region: "eu-west-1", - }: endpoints.Endpoint{ - Hostname: "oidc.eu-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-west-1", - }, - }, - endpoints.EndpointKey{ - Region: "eu-west-2", - }: endpoints.Endpoint{ - Hostname: "oidc.eu-west-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-west-2", - }, - }, - endpoints.EndpointKey{ - Region: "eu-west-3", - }: endpoints.Endpoint{ - Hostname: "oidc.eu-west-3.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "eu-west-3", - }, - }, - endpoints.EndpointKey{ - Region: "il-central-1", - }: endpoints.Endpoint{ - Hostname: "oidc.il-central-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "il-central-1", - }, - }, - endpoints.EndpointKey{ - Region: "me-central-1", - }: endpoints.Endpoint{ - Hostname: "oidc.me-central-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "me-central-1", - }, - }, - endpoints.EndpointKey{ - Region: "me-south-1", - }: endpoints.Endpoint{ - Hostname: "oidc.me-south-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "me-south-1", - }, - }, - endpoints.EndpointKey{ - Region: "sa-east-1", - }: endpoints.Endpoint{ - Hostname: "oidc.sa-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "sa-east-1", - }, - }, - endpoints.EndpointKey{ - Region: "us-east-1", - }: endpoints.Endpoint{ - Hostname: "oidc.us-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-east-1", - }, - }, - endpoints.EndpointKey{ - Region: "us-east-2", - }: endpoints.Endpoint{ - Hostname: "oidc.us-east-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-east-2", - }, - }, - endpoints.EndpointKey{ - Region: "us-west-1", - }: endpoints.Endpoint{ - Hostname: "oidc.us-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-west-1", - }, - }, - endpoints.EndpointKey{ - Region: "us-west-2", - }: endpoints.Endpoint{ - Hostname: "oidc.us-west-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-west-2", - }, - }, - }, - }, - { - ID: "aws-cn", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "oidc.{region}.api.amazonwebservices.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "oidc-fips.{region}.amazonaws.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "oidc-fips.{region}.api.amazonwebservices.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "oidc.{region}.amazonaws.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsCn, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "cn-north-1", - }: endpoints.Endpoint{ - Hostname: "oidc.cn-north-1.amazonaws.com.cn", - CredentialScope: endpoints.CredentialScope{ - Region: "cn-north-1", - }, - }, - endpoints.EndpointKey{ - Region: "cn-northwest-1", - }: endpoints.Endpoint{ - Hostname: "oidc.cn-northwest-1.amazonaws.com.cn", - CredentialScope: endpoints.CredentialScope{ - Region: "cn-northwest-1", - }, - }, - }, - }, - { - ID: "aws-iso", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "oidc-fips.{region}.c2s.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "oidc.{region}.c2s.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIso, - IsRegionalized: true, - }, - { - ID: "aws-iso-b", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "oidc-fips.{region}.sc2s.sgov.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "oidc.{region}.sc2s.sgov.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoB, - IsRegionalized: true, - }, - { - ID: "aws-iso-e", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "oidc-fips.{region}.cloud.adc-e.uk", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "oidc.{region}.cloud.adc-e.uk", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoE, - IsRegionalized: true, - }, - { - ID: "aws-iso-f", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "oidc-fips.{region}.csp.hci.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "oidc.{region}.csp.hci.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoF, - IsRegionalized: true, - }, - { - ID: "aws-us-gov", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "oidc.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "oidc-fips.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "oidc-fips.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "oidc.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsUsGov, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "us-gov-east-1", - }: endpoints.Endpoint{ - Hostname: "oidc.us-gov-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-gov-east-1", - }, - }, - endpoints.EndpointKey{ - Region: "us-gov-west-1", - }: endpoints.Endpoint{ - Hostname: "oidc.us-gov-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-gov-west-1", - }, - }, - }, - }, -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go deleted file mode 100644 index 55dd80d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go +++ /dev/null @@ -1,232 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "context" - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" - smithyauth "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net/http" -) - -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) -} - -type Options struct { - // Set of options to modify how an operation is invoked. These apply to all - // operations invoked for this client. Use functional options on operation call to - // modify this list for per operation behavior. - APIOptions []func(*middleware.Stack) error - - // The optional application specific identifier appended to the User-Agent header. - AppID string - - // This endpoint will be given as input to an EndpointResolverV2. It is used for - // providing a custom base endpoint that is subject to modifications by the - // processing EndpointResolverV2. - BaseEndpoint *string - - // Configures the events that will be sent to the configured logger. - ClientLogMode aws.ClientLogMode - - // The credentials object to use when signing requests. - Credentials aws.CredentialsProvider - - // The configuration DefaultsMode that the SDK should use when constructing the - // clients initial default settings. - DefaultsMode aws.DefaultsMode - - // The endpoint options to be used when attempting to resolve an endpoint. - EndpointOptions EndpointResolverOptions - - // The service endpoint resolver. - // - // Deprecated: Deprecated: EndpointResolver and WithEndpointResolver. Providing a - // value for this field will likely prevent you from using any endpoint-related - // service features released after the introduction of EndpointResolverV2 and - // BaseEndpoint. - // - // To migrate an EndpointResolver implementation that uses a custom endpoint, set - // the client option BaseEndpoint instead. - EndpointResolver EndpointResolver - - // Resolves the endpoint used for a particular service operation. This should be - // used over the deprecated EndpointResolver. - EndpointResolverV2 EndpointResolverV2 - - // Signature Version 4 (SigV4) Signer - HTTPSignerV4 HTTPSignerV4 - - // The logger writer interface to write logging messages to. - Logger logging.Logger - - // The client meter provider. - MeterProvider metrics.MeterProvider - - // The region to send requests to. (Required) - Region string - - // RetryMaxAttempts specifies the maximum number attempts an API client will call - // an operation that fails with a retryable error. A value of 0 is ignored, and - // will not be used to configure the API client created default retryer, or modify - // per operation call's retry max attempts. - // - // If specified in an operation call's functional options with a value that is - // different than the constructed client's Options, the Client's Retryer will be - // wrapped to use the operation's specific RetryMaxAttempts value. - RetryMaxAttempts int - - // RetryMode specifies the retry mode the API client will be created with, if - // Retryer option is not also specified. - // - // When creating a new API Clients this member will only be used if the Retryer - // Options member is nil. This value will be ignored if Retryer is not nil. - // - // Currently does not support per operation call overrides, may in the future. - RetryMode aws.RetryMode - - // Retryer guides how HTTP requests should be retried in case of recoverable - // failures. When nil the API client will use a default retryer. The kind of - // default retry created by the API client can be changed with the RetryMode - // option. - Retryer aws.Retryer - - // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set - // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You - // should not populate this structure programmatically, or rely on the values here - // within your applications. - RuntimeEnvironment aws.RuntimeEnvironment - - // The client tracer provider. - TracerProvider tracing.TracerProvider - - // The initial DefaultsMode used when the client options were constructed. If the - // DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved - // value was at that point in time. - // - // Currently does not support per operation call overrides, may in the future. - resolvedDefaultsMode aws.DefaultsMode - - // The HTTP client to invoke API calls with. Defaults to client's default HTTP - // implementation if nil. - HTTPClient HTTPClient - - // The auth scheme resolver which determines how to authenticate for each - // operation. - AuthSchemeResolver AuthSchemeResolver - - // The list of auth schemes supported by the client. - AuthSchemes []smithyhttp.AuthScheme -} - -// Copy creates a clone where the APIOptions list is deep copied. -func (o Options) Copy() Options { - to := o - to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) - copy(to.APIOptions, o.APIOptions) - - return to -} - -func (o Options) GetIdentityResolver(schemeID string) smithyauth.IdentityResolver { - if schemeID == "aws.auth#sigv4" { - return getSigV4IdentityResolver(o) - } - if schemeID == "smithy.api#noAuth" { - return &smithyauth.AnonymousIdentityResolver{} - } - return nil -} - -// WithAPIOptions returns a functional option for setting the Client's APIOptions -// option. -func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { - return func(o *Options) { - o.APIOptions = append(o.APIOptions, optFns...) - } -} - -// Deprecated: EndpointResolver and WithEndpointResolver. Providing a value for -// this field will likely prevent you from using any endpoint-related service -// features released after the introduction of EndpointResolverV2 and BaseEndpoint. -// -// To migrate an EndpointResolver implementation that uses a custom endpoint, set -// the client option BaseEndpoint instead. -func WithEndpointResolver(v EndpointResolver) func(*Options) { - return func(o *Options) { - o.EndpointResolver = v - } -} - -// WithEndpointResolverV2 returns a functional option for setting the Client's -// EndpointResolverV2 option. -func WithEndpointResolverV2(v EndpointResolverV2) func(*Options) { - return func(o *Options) { - o.EndpointResolverV2 = v - } -} - -func getSigV4IdentityResolver(o Options) smithyauth.IdentityResolver { - if o.Credentials != nil { - return &internalauthsmithy.CredentialsProviderAdapter{Provider: o.Credentials} - } - return nil -} - -// WithSigV4SigningName applies an override to the authentication workflow to -// use the given signing name for SigV4-authenticated operations. -// -// This is an advanced setting. The value here is FINAL, taking precedence over -// the resolved signing name from both auth scheme resolution and endpoint -// resolution. -func WithSigV4SigningName(name string) func(*Options) { - fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, - ) { - return next.HandleInitialize(awsmiddleware.SetSigningName(ctx, name), in) - } - return func(o *Options) { - o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { - return s.Initialize.Add( - middleware.InitializeMiddlewareFunc("withSigV4SigningName", fn), - middleware.Before, - ) - }) - } -} - -// WithSigV4SigningRegion applies an override to the authentication workflow to -// use the given signing region for SigV4-authenticated operations. -// -// This is an advanced setting. The value here is FINAL, taking precedence over -// the resolved signing region from both auth scheme resolution and endpoint -// resolution. -func WithSigV4SigningRegion(region string) func(*Options) { - fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, - ) { - return next.HandleInitialize(awsmiddleware.SetSigningRegion(ctx, region), in) - } - return func(o *Options) { - o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { - return s.Initialize.Add( - middleware.InitializeMiddlewareFunc("withSigV4SigningRegion", fn), - middleware.Before, - ) - }) - } -} - -func ignoreAnonymousAuth(options *Options) { - if aws.IsCredentialsProvider(options.Credentials, (*aws.AnonymousCredentials)(nil)) { - options.Credentials = nil - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/serializers.go deleted file mode 100644 index 1ad103d..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/serializers.go +++ /dev/null @@ -1,512 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "bytes" - "context" - "fmt" - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/encoding/httpbinding" - smithyjson "github.com/aws/smithy-go/encoding/json" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -type awsRestjson1_serializeOpCreateToken struct { -} - -func (*awsRestjson1_serializeOpCreateToken) ID() string { - return "OperationSerializer" -} - -func (m *awsRestjson1_serializeOpCreateToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateTokenInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - opPath, opQuery := httpbinding.SplitURI("/token") - request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) - request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) - request.Method = "POST" - var restEncoder *httpbinding.Encoder - if request.URL.RawPath == "" { - restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - } else { - request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) - restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) - } - - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - restEncoder.SetHeader("Content-Type").String("application/json") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsRestjson1_serializeOpDocumentCreateTokenInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = restEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} -func awsRestjson1_serializeOpHttpBindingsCreateTokenInput(v *CreateTokenInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - return nil -} - -func awsRestjson1_serializeOpDocumentCreateTokenInput(v *CreateTokenInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ClientId != nil { - ok := object.Key("clientId") - ok.String(*v.ClientId) - } - - if v.ClientSecret != nil { - ok := object.Key("clientSecret") - ok.String(*v.ClientSecret) - } - - if v.Code != nil { - ok := object.Key("code") - ok.String(*v.Code) - } - - if v.CodeVerifier != nil { - ok := object.Key("codeVerifier") - ok.String(*v.CodeVerifier) - } - - if v.DeviceCode != nil { - ok := object.Key("deviceCode") - ok.String(*v.DeviceCode) - } - - if v.GrantType != nil { - ok := object.Key("grantType") - ok.String(*v.GrantType) - } - - if v.RedirectUri != nil { - ok := object.Key("redirectUri") - ok.String(*v.RedirectUri) - } - - if v.RefreshToken != nil { - ok := object.Key("refreshToken") - ok.String(*v.RefreshToken) - } - - if v.Scope != nil { - ok := object.Key("scope") - if err := awsRestjson1_serializeDocumentScopes(v.Scope, ok); err != nil { - return err - } - } - - return nil -} - -type awsRestjson1_serializeOpCreateTokenWithIAM struct { -} - -func (*awsRestjson1_serializeOpCreateTokenWithIAM) ID() string { - return "OperationSerializer" -} - -func (m *awsRestjson1_serializeOpCreateTokenWithIAM) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*CreateTokenWithIAMInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - opPath, opQuery := httpbinding.SplitURI("/token?aws_iam=t") - request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) - request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) - request.Method = "POST" - var restEncoder *httpbinding.Encoder - if request.URL.RawPath == "" { - restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - } else { - request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) - restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) - } - - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - restEncoder.SetHeader("Content-Type").String("application/json") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsRestjson1_serializeOpDocumentCreateTokenWithIAMInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = restEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} -func awsRestjson1_serializeOpHttpBindingsCreateTokenWithIAMInput(v *CreateTokenWithIAMInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - return nil -} - -func awsRestjson1_serializeOpDocumentCreateTokenWithIAMInput(v *CreateTokenWithIAMInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.Assertion != nil { - ok := object.Key("assertion") - ok.String(*v.Assertion) - } - - if v.ClientId != nil { - ok := object.Key("clientId") - ok.String(*v.ClientId) - } - - if v.Code != nil { - ok := object.Key("code") - ok.String(*v.Code) - } - - if v.CodeVerifier != nil { - ok := object.Key("codeVerifier") - ok.String(*v.CodeVerifier) - } - - if v.GrantType != nil { - ok := object.Key("grantType") - ok.String(*v.GrantType) - } - - if v.RedirectUri != nil { - ok := object.Key("redirectUri") - ok.String(*v.RedirectUri) - } - - if v.RefreshToken != nil { - ok := object.Key("refreshToken") - ok.String(*v.RefreshToken) - } - - if v.RequestedTokenType != nil { - ok := object.Key("requestedTokenType") - ok.String(*v.RequestedTokenType) - } - - if v.Scope != nil { - ok := object.Key("scope") - if err := awsRestjson1_serializeDocumentScopes(v.Scope, ok); err != nil { - return err - } - } - - if v.SubjectToken != nil { - ok := object.Key("subjectToken") - ok.String(*v.SubjectToken) - } - - if v.SubjectTokenType != nil { - ok := object.Key("subjectTokenType") - ok.String(*v.SubjectTokenType) - } - - return nil -} - -type awsRestjson1_serializeOpRegisterClient struct { -} - -func (*awsRestjson1_serializeOpRegisterClient) ID() string { - return "OperationSerializer" -} - -func (m *awsRestjson1_serializeOpRegisterClient) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*RegisterClientInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - opPath, opQuery := httpbinding.SplitURI("/client/register") - request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) - request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) - request.Method = "POST" - var restEncoder *httpbinding.Encoder - if request.URL.RawPath == "" { - restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - } else { - request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) - restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) - } - - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - restEncoder.SetHeader("Content-Type").String("application/json") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsRestjson1_serializeOpDocumentRegisterClientInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = restEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} -func awsRestjson1_serializeOpHttpBindingsRegisterClientInput(v *RegisterClientInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - return nil -} - -func awsRestjson1_serializeOpDocumentRegisterClientInput(v *RegisterClientInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ClientName != nil { - ok := object.Key("clientName") - ok.String(*v.ClientName) - } - - if v.ClientType != nil { - ok := object.Key("clientType") - ok.String(*v.ClientType) - } - - if v.EntitledApplicationArn != nil { - ok := object.Key("entitledApplicationArn") - ok.String(*v.EntitledApplicationArn) - } - - if v.GrantTypes != nil { - ok := object.Key("grantTypes") - if err := awsRestjson1_serializeDocumentGrantTypes(v.GrantTypes, ok); err != nil { - return err - } - } - - if v.IssuerUrl != nil { - ok := object.Key("issuerUrl") - ok.String(*v.IssuerUrl) - } - - if v.RedirectUris != nil { - ok := object.Key("redirectUris") - if err := awsRestjson1_serializeDocumentRedirectUris(v.RedirectUris, ok); err != nil { - return err - } - } - - if v.Scopes != nil { - ok := object.Key("scopes") - if err := awsRestjson1_serializeDocumentScopes(v.Scopes, ok); err != nil { - return err - } - } - - return nil -} - -type awsRestjson1_serializeOpStartDeviceAuthorization struct { -} - -func (*awsRestjson1_serializeOpStartDeviceAuthorization) ID() string { - return "OperationSerializer" -} - -func (m *awsRestjson1_serializeOpStartDeviceAuthorization) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*StartDeviceAuthorizationInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - opPath, opQuery := httpbinding.SplitURI("/device_authorization") - request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) - request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) - request.Method = "POST" - var restEncoder *httpbinding.Encoder - if request.URL.RawPath == "" { - restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - } else { - request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) - restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) - } - - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - restEncoder.SetHeader("Content-Type").String("application/json") - - jsonEncoder := smithyjson.NewEncoder() - if err := awsRestjson1_serializeOpDocumentStartDeviceAuthorizationInput(input, jsonEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = restEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} -func awsRestjson1_serializeOpHttpBindingsStartDeviceAuthorizationInput(v *StartDeviceAuthorizationInput, encoder *httpbinding.Encoder) error { - if v == nil { - return fmt.Errorf("unsupported serialization of nil %T", v) - } - - return nil -} - -func awsRestjson1_serializeOpDocumentStartDeviceAuthorizationInput(v *StartDeviceAuthorizationInput, value smithyjson.Value) error { - object := value.Object() - defer object.Close() - - if v.ClientId != nil { - ok := object.Key("clientId") - ok.String(*v.ClientId) - } - - if v.ClientSecret != nil { - ok := object.Key("clientSecret") - ok.String(*v.ClientSecret) - } - - if v.StartUrl != nil { - ok := object.Key("startUrl") - ok.String(*v.StartUrl) - } - - return nil -} - -func awsRestjson1_serializeDocumentGrantTypes(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsRestjson1_serializeDocumentRedirectUris(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsRestjson1_serializeDocumentScopes(v []string, value smithyjson.Value) error { - array := value.Array() - defer array.Close() - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/errors.go deleted file mode 100644 index 2cfe7b4..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/errors.go +++ /dev/null @@ -1,428 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - "fmt" - smithy "github.com/aws/smithy-go" -) - -// You do not have sufficient access to perform this action. -type AccessDeniedException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *AccessDeniedException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AccessDeniedException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AccessDeniedException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AccessDeniedException" - } - return *e.ErrorCodeOverride -} -func (e *AccessDeniedException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that a request to authorize a client with an access user session -// token is pending. -type AuthorizationPendingException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *AuthorizationPendingException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *AuthorizationPendingException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *AuthorizationPendingException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "AuthorizationPendingException" - } - return *e.ErrorCodeOverride -} -func (e *AuthorizationPendingException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that the token issued by the service is expired and is no longer -// valid. -type ExpiredTokenException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *ExpiredTokenException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ExpiredTokenException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ExpiredTokenException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ExpiredTokenException" - } - return *e.ErrorCodeOverride -} -func (e *ExpiredTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that an error from the service occurred while trying to process a -// request. -type InternalServerException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *InternalServerException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InternalServerException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InternalServerException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InternalServerException" - } - return *e.ErrorCodeOverride -} -func (e *InternalServerException) ErrorFault() smithy.ErrorFault { return smithy.FaultServer } - -// Indicates that the clientId or clientSecret in the request is invalid. For -// example, this can occur when a client sends an incorrect clientId or an expired -// clientSecret . -type InvalidClientException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *InvalidClientException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidClientException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidClientException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidClientException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidClientException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that the client information sent in the request during registration -// is invalid. -type InvalidClientMetadataException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *InvalidClientMetadataException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidClientMetadataException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidClientMetadataException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidClientMetadataException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidClientMetadataException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that a request contains an invalid grant. This can occur if a client -// makes a CreateTokenrequest with an invalid grant type. -type InvalidGrantException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *InvalidGrantException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidGrantException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidGrantException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidGrantException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidGrantException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that one or more redirect URI in the request is not supported for -// this operation. -type InvalidRedirectUriException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *InvalidRedirectUriException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidRedirectUriException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidRedirectUriException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidRedirectUriException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidRedirectUriException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that something is wrong with the input to the request. For example, a -// required parameter might be missing or out of range. -type InvalidRequestException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *InvalidRequestException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidRequestException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidRequestException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidRequestException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidRequestException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that a token provided as input to the request was issued by and is -// only usable by calling IAM Identity Center endpoints in another region. -type InvalidRequestRegionException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - Endpoint *string - Region *string - - noSmithyDocumentSerde -} - -func (e *InvalidRequestRegionException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidRequestRegionException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidRequestRegionException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidRequestRegionException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidRequestRegionException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that the scope provided in the request is invalid. -type InvalidScopeException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *InvalidScopeException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidScopeException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidScopeException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidScopeException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidScopeException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that the client is making the request too frequently and is more than -// the service can handle. -type SlowDownException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *SlowDownException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *SlowDownException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *SlowDownException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "SlowDownException" - } - return *e.ErrorCodeOverride -} -func (e *SlowDownException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that the client is not currently authorized to make the request. This -// can happen when a clientId is not issued for a public client. -type UnauthorizedClientException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *UnauthorizedClientException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnauthorizedClientException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnauthorizedClientException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnauthorizedClientException" - } - return *e.ErrorCodeOverride -} -func (e *UnauthorizedClientException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Indicates that the grant type in the request is not supported by the service. -type UnsupportedGrantTypeException struct { - Message *string - - ErrorCodeOverride *string - - Error_ *string - Error_description *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedGrantTypeException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedGrantTypeException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedGrantTypeException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedGrantTypeException" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedGrantTypeException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/types.go deleted file mode 100644 index 0ec0789..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/types.go +++ /dev/null @@ -1,9 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - smithydocument "github.com/aws/smithy-go/document" -) - -type noSmithyDocumentSerde = smithydocument.NoSerde diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/validators.go deleted file mode 100644 index 9c17e4c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/validators.go +++ /dev/null @@ -1,184 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package ssooidc - -import ( - "context" - "fmt" - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/middleware" -) - -type validateOpCreateToken struct { -} - -func (*validateOpCreateToken) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateToken) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateTokenInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateTokenInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpCreateTokenWithIAM struct { -} - -func (*validateOpCreateTokenWithIAM) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpCreateTokenWithIAM) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*CreateTokenWithIAMInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpCreateTokenWithIAMInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpRegisterClient struct { -} - -func (*validateOpRegisterClient) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpRegisterClient) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*RegisterClientInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpRegisterClientInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpStartDeviceAuthorization struct { -} - -func (*validateOpStartDeviceAuthorization) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpStartDeviceAuthorization) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*StartDeviceAuthorizationInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpStartDeviceAuthorizationInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -func addOpCreateTokenValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateToken{}, middleware.After) -} - -func addOpCreateTokenWithIAMValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpCreateTokenWithIAM{}, middleware.After) -} - -func addOpRegisterClientValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpRegisterClient{}, middleware.After) -} - -func addOpStartDeviceAuthorizationValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpStartDeviceAuthorization{}, middleware.After) -} - -func validateOpCreateTokenInput(v *CreateTokenInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateTokenInput"} - if v.ClientId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ClientId")) - } - if v.ClientSecret == nil { - invalidParams.Add(smithy.NewErrParamRequired("ClientSecret")) - } - if v.GrantType == nil { - invalidParams.Add(smithy.NewErrParamRequired("GrantType")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpCreateTokenWithIAMInput(v *CreateTokenWithIAMInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "CreateTokenWithIAMInput"} - if v.ClientId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ClientId")) - } - if v.GrantType == nil { - invalidParams.Add(smithy.NewErrParamRequired("GrantType")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpRegisterClientInput(v *RegisterClientInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "RegisterClientInput"} - if v.ClientName == nil { - invalidParams.Add(smithy.NewErrParamRequired("ClientName")) - } - if v.ClientType == nil { - invalidParams.Add(smithy.NewErrParamRequired("ClientType")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpStartDeviceAuthorizationInput(v *StartDeviceAuthorizationInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "StartDeviceAuthorizationInput"} - if v.ClientId == nil { - invalidParams.Add(smithy.NewErrParamRequired("ClientId")) - } - if v.ClientSecret == nil { - invalidParams.Add(smithy.NewErrParamRequired("ClientSecret")) - } - if v.StartUrl == nil { - invalidParams.Add(smithy.NewErrParamRequired("StartUrl")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md deleted file mode 100644 index 42c252b..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md +++ /dev/null @@ -1,772 +0,0 @@ -# v1.41.5 (2025-12-09) - -* No change notes available for this release. - -# v1.41.4 (2025-12-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.41.3 (2025-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.24.0. Notably this version of the library reduces the allocation footprint of the middleware system. We observe a ~10% reduction in allocations per SDK call with this change. - -# v1.41.2 (2025-11-25) - -* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234 - -# v1.41.1 (2025-11-19.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.41.0 (2025-11-19) - -* **Feature**: IAM now supports outbound identity federation via the STS GetWebIdentityToken API, enabling AWS workloads to securely authenticate with external services using short-lived JSON Web Tokens. - -# v1.40.2 (2025-11-12) - -* **Bug Fix**: Further reduce allocation overhead when the metrics system isn't in-use. -* **Bug Fix**: Reduce allocation overhead when the client doesn't have any HTTP interceptors configured. -* **Bug Fix**: Remove blank trace spans towards the beginning of the request that added no additional information. This conveys a slight reduction in overall allocations. - -# v1.40.1 (2025-11-11) - -* **Bug Fix**: Return validation error if input region is not a valid host label. - -# v1.40.0 (2025-11-10) - -* **Feature**: Added GetDelegatedAccessToken API, which is not available for general use at this time. - -# v1.39.1 (2025-11-04) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. - -# v1.39.0 (2025-10-30) - -* **Feature**: Update endpoint ruleset parameters casing -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.9 (2025-10-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.8 (2025-10-22) - -* No change notes available for this release. - -# v1.38.7 (2025-10-16) - -* **Dependency Update**: Bump minimum Go version to 1.23. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.6 (2025-09-26) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.5 (2025-09-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.4 (2025-09-10) - -* No change notes available for this release. - -# v1.38.3 (2025-09-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.2 (2025-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.1 (2025-08-27) - -* **Dependency Update**: Update to smithy-go v1.23.0. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.38.0 (2025-08-21) - -* **Feature**: Remove incorrect endpoint tests -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.37.1 (2025-08-20) - -* **Bug Fix**: Remove unused deserialization code. - -# v1.37.0 (2025-08-11) - -* **Feature**: Add support for configuring per-service Options via callback on global config. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.36.0 (2025-08-04) - -* **Feature**: Support configurable auth scheme preferences in service clients via AWS_AUTH_SCHEME_PREFERENCE in the environment, auth_scheme_preference in the config file, and through in-code settings on LoadDefaultConfig and client constructor methods. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.35.1 (2025-07-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.35.0 (2025-07-28) - -* **Feature**: Add support for HTTP interceptors. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.34.1 (2025-07-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.34.0 (2025-06-17) - -* **Feature**: The AWS Security Token Service APIs AssumeRoleWithSAML and AssumeRoleWithWebIdentity can now be invoked without pre-configured AWS credentials in the SDK configuration. -* **Dependency Update**: Update to smithy-go v1.22.4. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.21 (2025-06-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.20 (2025-06-06) - -* No change notes available for this release. - -# v1.33.19 (2025-04-10) - -* No change notes available for this release. - -# v1.33.18 (2025-04-03) - -* No change notes available for this release. - -# v1.33.17 (2025-03-04.2) - -* **Bug Fix**: Add assurance test for operation order. - -# v1.33.16 (2025-02-27) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.15 (2025-02-18) - -* **Bug Fix**: Bump go version to 1.22 -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.14 (2025-02-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.13 (2025-02-04) - -* No change notes available for this release. - -# v1.33.12 (2025-01-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.11 (2025-01-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.10 (2025-01-24) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade to smithy-go v1.22.2. - -# v1.33.9 (2025-01-17) - -* **Bug Fix**: Fix bug where credentials weren't refreshed during retry loop. - -# v1.33.8 (2025-01-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.7 (2025-01-14) - -* No change notes available for this release. - -# v1.33.6 (2025-01-10) - -* **Documentation**: Fixed typos in the descriptions. - -# v1.33.5 (2025-01-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.4 (2025-01-08) - -* No change notes available for this release. - -# v1.33.3 (2024-12-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.2 (2024-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.1 (2024-11-18) - -* **Dependency Update**: Update to smithy-go v1.22.1. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.33.0 (2024-11-14) - -* **Feature**: This release introduces the new API 'AssumeRoot', which returns short-term credentials that you can use to perform privileged tasks. - -# v1.32.4 (2024-11-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.32.3 (2024-10-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.32.2 (2024-10-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.32.1 (2024-10-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.32.0 (2024-10-04) - -* **Feature**: Add support for HTTP client metrics. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.31.4 (2024-10-03) - -* No change notes available for this release. - -# v1.31.3 (2024-09-27) - -* No change notes available for this release. - -# v1.31.2 (2024-09-25) - -* No change notes available for this release. - -# v1.31.1 (2024-09-23) - -* No change notes available for this release. - -# v1.31.0 (2024-09-20) - -* **Feature**: Add tracing and metrics support to service clients. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.30.8 (2024-09-17) - -* **Bug Fix**: **BREAKFIX**: Only generate AccountIDEndpointMode config for services that use it. This is a compiler break, but removes no actual functionality, as no services currently use the account ID in endpoint resolution. - -# v1.30.7 (2024-09-04) - -* No change notes available for this release. - -# v1.30.6 (2024-09-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.30.5 (2024-08-22) - -* No change notes available for this release. - -# v1.30.4 (2024-08-15) - -* **Dependency Update**: Bump minimum Go version to 1.21. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.30.3 (2024-07-10.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.30.2 (2024-07-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.30.1 (2024-06-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.30.0 (2024-06-26) - -* **Feature**: Support list-of-string endpoint parameter. - -# v1.29.1 (2024-06-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.29.0 (2024-06-18) - -* **Feature**: Track usage of various AWS SDK features in user-agent string. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.13 (2024-06-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.12 (2024-06-07) - -* **Bug Fix**: Add clock skew correction on all service clients -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.11 (2024-06-03) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.10 (2024-05-23) - -* No change notes available for this release. - -# v1.28.9 (2024-05-16) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.8 (2024-05-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.7 (2024-05-08) - -* **Bug Fix**: GoDoc improvement - -# v1.28.6 (2024-03-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.5 (2024-03-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.4 (2024-03-07) - -* **Bug Fix**: Remove dependency on go-cmp. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.3 (2024-03-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.2 (2024-03-04) - -* **Bug Fix**: Update internal/presigned-url dependency for corrected API name. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.1 (2024-02-23) - -* **Bug Fix**: Move all common, SDK-side middleware stack ops into the service client module to prevent cross-module compatibility issues in the future. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.28.0 (2024-02-22) - -* **Feature**: Add middleware stack snapshot tests. - -# v1.27.2 (2024-02-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.27.1 (2024-02-20) - -* **Bug Fix**: When sourcing values for a service's `EndpointParameters`, the lack of a configured region (i.e. `options.Region == ""`) will now translate to a `nil` value for `EndpointParameters.Region` instead of a pointer to the empty string `""`. This will result in a much more explicit error when calling an operation instead of an obscure hostname lookup failure. - -# v1.27.0 (2024-02-13) - -* **Feature**: Bump minimum Go version to 1.20 per our language support policy. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.7 (2024-01-04) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.6 (2023-12-20) - -* No change notes available for this release. - -# v1.26.5 (2023-12-08) - -* **Bug Fix**: Reinstate presence of default Retryer in functional options, but still respect max attempts set therein. - -# v1.26.4 (2023-12-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.3 (2023-12-06) - -* **Bug Fix**: Restore pre-refactor auth behavior where all operations could technically be performed anonymously. -* **Bug Fix**: STS `AssumeRoleWithSAML` and `AssumeRoleWithWebIdentity` would incorrectly attempt to use SigV4 authentication. - -# v1.26.2 (2023-12-01) - -* **Bug Fix**: Correct wrapping of errors in authentication workflow. -* **Bug Fix**: Correctly recognize cache-wrapped instances of AnonymousCredentials at client construction. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.1 (2023-11-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.26.0 (2023-11-29) - -* **Feature**: Expose Options() accessor on service clients. -* **Documentation**: Documentation updates for AWS Security Token Service. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.6 (2023-11-28.2) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.5 (2023-11-28) - -* **Bug Fix**: Respect setting RetryMaxAttempts in functional options at client construction. - -# v1.25.4 (2023-11-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.3 (2023-11-17) - -* **Documentation**: API updates for the AWS Security Token Service - -# v1.25.2 (2023-11-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.1 (2023-11-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.25.0 (2023-11-01) - -* **Feature**: Adds support for configured endpoints via environment variables and the AWS shared configuration file. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.24.0 (2023-10-31) - -* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.2 (2023-10-12) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.1 (2023-10-06) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.23.0 (2023-10-02) - -* **Feature**: STS API updates for assumeRole - -# v1.22.0 (2023-09-18) - -* **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. -* **Feature**: Adds several endpoint ruleset changes across all models: smaller rulesets, removed non-unique regional endpoints, fixes FIPS and DualStack endpoints, and make region not required in SDK::Endpoint. Additional breakfix to cognito-sync field. - -# v1.21.5 (2023-08-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.4 (2023-08-18) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.3 (2023-08-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.2 (2023-08-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.21.1 (2023-08-01) - -* No change notes available for this release. - -# v1.21.0 (2023-07-31) - -* **Feature**: Adds support for smithy-modeled endpoint resolution. A new rules-based endpoint resolution will be added to the SDK which will supercede and deprecate existing endpoint resolution. Specifically, EndpointResolver will be deprecated while BaseEndpoint and EndpointResolverV2 will take its place. For more information, please see the Endpoints section in our Developer Guide. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.1 (2023-07-28) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.20.0 (2023-07-25) - -* **Feature**: API updates for the AWS Security Token Service - -# v1.19.3 (2023-07-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.19.2 (2023-06-15) - -* No change notes available for this release. - -# v1.19.1 (2023-06-13) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.19.0 (2023-05-08) - -* **Feature**: Documentation updates for AWS Security Token Service. - -# v1.18.11 (2023-05-04) - -* No change notes available for this release. - -# v1.18.10 (2023-04-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.9 (2023-04-10) - -* No change notes available for this release. - -# v1.18.8 (2023-04-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.7 (2023-03-21) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.6 (2023-03-10) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.5 (2023-02-22) - -* **Bug Fix**: Prevent nil pointer dereference when retrieving error codes. - -# v1.18.4 (2023-02-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.18.3 (2023-02-03) - -* **Dependency Update**: Updated to the latest SDK module versions -* **Dependency Update**: Upgrade smithy to 1.27.2 and correct empty query list serialization. - -# v1.18.2 (2023-01-25) - -* **Documentation**: Doc only change to update wording in a key topic - -# v1.18.1 (2023-01-23) - -* No change notes available for this release. - -# v1.18.0 (2023-01-05) - -* **Feature**: Add `ErrorCodeOverride` field to all error structs (aws/smithy-go#401). - -# v1.17.7 (2022-12-15) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.6 (2022-12-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.5 (2022-11-22) - -* No change notes available for this release. - -# v1.17.4 (2022-11-17) - -* **Documentation**: Documentation updates for AWS Security Token Service. - -# v1.17.3 (2022-11-16) - -* No change notes available for this release. - -# v1.17.2 (2022-11-10) - -* No change notes available for this release. - -# v1.17.1 (2022-10-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.17.0 (2022-10-21) - -* **Feature**: Add presign functionality for sts:AssumeRole operation -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.19 (2022-09-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.18 (2022-09-14) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.17 (2022-09-02) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.16 (2022-08-31) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.15 (2022-08-30) - -* No change notes available for this release. - -# v1.16.14 (2022-08-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.13 (2022-08-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.12 (2022-08-09) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.11 (2022-08-08) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.10 (2022-08-01) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.9 (2022-07-05) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.8 (2022-06-29) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.7 (2022-06-07) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.6 (2022-05-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.5 (2022-05-16) - -* **Documentation**: Documentation updates for AWS Security Token Service. - -# v1.16.4 (2022-04-25) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.3 (2022-03-30) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.2 (2022-03-24) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.1 (2022-03-23) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.16.0 (2022-03-08) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Documentation**: Updated service client model to latest release. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.15.0 (2022-02-24) - -* **Feature**: API client updated -* **Feature**: Adds RetryMaxAttempts and RetryMod to API client Options. This allows the API clients' default Retryer to be configured from the shared configuration files or environment variables. Adding a new Retry mode of `Adaptive`. `Adaptive` retry mode is an experimental mode, adding client rate limiting when throttles reponses are received from an API. See [retry.AdaptiveMode](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry#AdaptiveMode) for more details, and configuration options. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.14.0 (2022-01-14) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.13.0 (2022-01-07) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.12.0 (2021-12-21) - -* **Feature**: Updated to latest service endpoints - -# v1.11.1 (2021-12-02) - -* **Bug Fix**: Fixes a bug that prevented aws.EndpointResolverWithOptions from being used by the service client. ([#1514](https://github.com/aws/aws-sdk-go-v2/pull/1514)) -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.11.0 (2021-11-30) - -* **Feature**: API client updated - -# v1.10.1 (2021-11-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.10.0 (2021-11-12) - -* **Feature**: Service clients now support custom endpoints that have an initial URI path defined. - -# v1.9.0 (2021-11-06) - -* **Feature**: The SDK now supports configuration of FIPS and DualStack endpoints using environment variables, shared configuration, or programmatically. -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.8.0 (2021-10-21) - -* **Feature**: API client updated -* **Feature**: Updated to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.7.2 (2021-10-11) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.7.1 (2021-09-17) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.7.0 (2021-08-27) - -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.2 (2021-08-19) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.1 (2021-08-04) - -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version. -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.6.0 (2021-07-15) - -* **Feature**: The ErrorCode method on generated service error types has been corrected to match the API model. -* **Documentation**: Updated service model to latest revision. -* **Dependency Update**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.5.0 (2021-06-25) - -* **Feature**: API client updated -* **Feature**: Updated `github.com/aws/smithy-go` to latest version -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.1 (2021-05-20) - -* **Dependency Update**: Updated to the latest SDK module versions - -# v1.4.0 (2021-05-14) - -* **Feature**: Constant has been added to modules to enable runtime version inspection for reporting. -* **Dependency Update**: Updated to the latest SDK module versions - diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go deleted file mode 100644 index 70228d0..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go +++ /dev/null @@ -1,1101 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "errors" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/aws/defaults" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/protocol/query" - "github.com/aws/aws-sdk-go-v2/aws/retry" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" - internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" - internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" - internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" - internalmiddleware "github.com/aws/aws-sdk-go-v2/internal/middleware" - acceptencodingcust "github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding" - presignedurlcust "github.com/aws/aws-sdk-go-v2/service/internal/presigned-url" - smithy "github.com/aws/smithy-go" - smithyauth "github.com/aws/smithy-go/auth" - smithydocument "github.com/aws/smithy-go/document" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net" - "net/http" - "sync/atomic" - "time" -) - -const ServiceID = "STS" -const ServiceAPIVersion = "2011-06-15" - -type operationMetrics struct { - Duration metrics.Float64Histogram - SerializeDuration metrics.Float64Histogram - ResolveIdentityDuration metrics.Float64Histogram - ResolveEndpointDuration metrics.Float64Histogram - SignRequestDuration metrics.Float64Histogram - DeserializeDuration metrics.Float64Histogram -} - -func (m *operationMetrics) histogramFor(name string) metrics.Float64Histogram { - switch name { - case "client.call.duration": - return m.Duration - case "client.call.serialization_duration": - return m.SerializeDuration - case "client.call.resolve_identity_duration": - return m.ResolveIdentityDuration - case "client.call.resolve_endpoint_duration": - return m.ResolveEndpointDuration - case "client.call.signing_duration": - return m.SignRequestDuration - case "client.call.deserialization_duration": - return m.DeserializeDuration - default: - panic("unrecognized operation metric") - } -} - -func timeOperationMetric[T any]( - ctx context.Context, metric string, fn func() (T, error), - opts ...metrics.RecordMetricOption, -) (T, error) { - mm := getOperationMetrics(ctx) - if mm == nil { // not using the metrics system - return fn() - } - - instr := mm.histogramFor(metric) - opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) - - start := time.Now() - v, err := fn() - end := time.Now() - - elapsed := end.Sub(start) - instr.Record(ctx, float64(elapsed)/1e9, opts...) - return v, err -} - -func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() { - mm := getOperationMetrics(ctx) - if mm == nil { // not using the metrics system - return func() {} - } - - instr := mm.histogramFor(metric) - opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) - - var ended bool - start := time.Now() - return func() { - if ended { - return - } - ended = true - - end := time.Now() - - elapsed := end.Sub(start) - instr.Record(ctx, float64(elapsed)/1e9, opts...) - } -} - -func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { - return func(o *metrics.RecordMetricOptions) { - o.Properties.Set("rpc.service", middleware.GetServiceID(ctx)) - o.Properties.Set("rpc.method", middleware.GetOperationName(ctx)) - } -} - -type operationMetricsKey struct{} - -func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) { - if _, ok := mp.(metrics.NopMeterProvider); ok { - // not using the metrics system - setting up the metrics context is a memory-intensive operation - // so we should skip it in this case - return parent, nil - } - - meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/sts") - om := &operationMetrics{} - - var err error - - om.Duration, err = operationMetricTimer(meter, "client.call.duration", - "Overall call duration (including retries and time to send or receive request and response body)") - if err != nil { - return nil, err - } - om.SerializeDuration, err = operationMetricTimer(meter, "client.call.serialization_duration", - "The time it takes to serialize a message body") - if err != nil { - return nil, err - } - om.ResolveIdentityDuration, err = operationMetricTimer(meter, "client.call.auth.resolve_identity_duration", - "The time taken to acquire an identity (AWS credentials, bearer token, etc) from an Identity Provider") - if err != nil { - return nil, err - } - om.ResolveEndpointDuration, err = operationMetricTimer(meter, "client.call.resolve_endpoint_duration", - "The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request") - if err != nil { - return nil, err - } - om.SignRequestDuration, err = operationMetricTimer(meter, "client.call.auth.signing_duration", - "The time it takes to sign a request") - if err != nil { - return nil, err - } - om.DeserializeDuration, err = operationMetricTimer(meter, "client.call.deserialization_duration", - "The time it takes to deserialize a message body") - if err != nil { - return nil, err - } - - return context.WithValue(parent, operationMetricsKey{}, om), nil -} - -func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Histogram, error) { - return m.Float64Histogram(name, func(o *metrics.InstrumentOptions) { - o.UnitLabel = "s" - o.Description = desc - }) -} - -func getOperationMetrics(ctx context.Context) *operationMetrics { - if v := ctx.Value(operationMetricsKey{}); v != nil { - return v.(*operationMetrics) - } - return nil -} - -func operationTracer(p tracing.TracerProvider) tracing.Tracer { - return p.Tracer("github.com/aws/aws-sdk-go-v2/service/sts") -} - -// Client provides the API client to make operations call for AWS Security Token -// Service. -type Client struct { - options Options - - // Difference between the time reported by the server and the client - timeOffset *atomic.Int64 -} - -// New returns an initialized Client based on the functional options. Provide -// additional functional options to further configure the behavior of the client, -// such as changing the client's endpoint or adding custom middleware behavior. -func New(options Options, optFns ...func(*Options)) *Client { - options = options.Copy() - - resolveDefaultLogger(&options) - - setResolvedDefaultsMode(&options) - - resolveRetryer(&options) - - resolveHTTPClient(&options) - - resolveHTTPSignerV4(&options) - - resolveEndpointResolverV2(&options) - - resolveTracerProvider(&options) - - resolveMeterProvider(&options) - - resolveAuthSchemeResolver(&options) - - for _, fn := range optFns { - fn(&options) - } - - finalizeRetryMaxAttempts(&options) - - ignoreAnonymousAuth(&options) - - wrapWithAnonymousAuth(&options) - - resolveAuthSchemes(&options) - - client := &Client{ - options: options, - } - - initializeTimeOffsetResolver(client) - - return client -} - -// Options returns a copy of the client configuration. -// -// Callers SHOULD NOT perform mutations on any inner structures within client -// config. Config overrides should instead be made on a per-operation basis through -// functional options. -func (c *Client) Options() Options { - return c.options.Copy() -} - -func (c *Client) invokeOperation( - ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error, -) ( - result interface{}, metadata middleware.Metadata, err error, -) { - ctx = middleware.ClearStackValues(ctx) - ctx = middleware.WithServiceID(ctx, ServiceID) - ctx = middleware.WithOperationName(ctx, opID) - - stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) - options := c.options.Copy() - - for _, fn := range optFns { - fn(&options) - } - - finalizeOperationRetryMaxAttempts(&options, *c) - - finalizeClientEndpointResolverOptions(&options) - - for _, fn := range stackFns { - if err := fn(stack, options); err != nil { - return nil, metadata, err - } - } - - for _, fn := range options.APIOptions { - if err := fn(stack); err != nil { - return nil, metadata, err - } - } - - ctx, err = withOperationMetrics(ctx, options.MeterProvider) - if err != nil { - return nil, metadata, err - } - - tracer := operationTracer(options.TracerProvider) - spanName := fmt.Sprintf("%s.%s", ServiceID, opID) - - ctx = tracing.WithOperationTracer(ctx, tracer) - - ctx, span := tracer.StartSpan(ctx, spanName, func(o *tracing.SpanOptions) { - o.Kind = tracing.SpanKindClient - o.Properties.Set("rpc.system", "aws-api") - o.Properties.Set("rpc.method", opID) - o.Properties.Set("rpc.service", ServiceID) - }) - endTimer := startMetricTimer(ctx, "client.call.duration") - defer endTimer() - defer span.End() - - handler := smithyhttp.NewClientHandlerWithOptions(options.HTTPClient, func(o *smithyhttp.ClientHandler) { - o.Meter = options.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sts") - }) - decorated := middleware.DecorateHandler(handler, stack) - result, metadata, err = decorated.Handle(ctx, params) - if err != nil { - span.SetProperty("exception.type", fmt.Sprintf("%T", err)) - span.SetProperty("exception.message", err.Error()) - - var aerr smithy.APIError - if errors.As(err, &aerr) { - span.SetProperty("api.error_code", aerr.ErrorCode()) - span.SetProperty("api.error_message", aerr.ErrorMessage()) - span.SetProperty("api.error_fault", aerr.ErrorFault().String()) - } - - err = &smithy.OperationError{ - ServiceID: ServiceID, - OperationName: opID, - Err: err, - } - } - - span.SetProperty("error", err != nil) - if err == nil { - span.SetStatus(tracing.SpanStatusOK) - } else { - span.SetStatus(tracing.SpanStatusError) - } - - return result, metadata, err -} - -type operationInputKey struct{} - -func setOperationInput(ctx context.Context, input interface{}) context.Context { - return middleware.WithStackValue(ctx, operationInputKey{}, input) -} - -func getOperationInput(ctx context.Context) interface{} { - return middleware.GetStackValue(ctx, operationInputKey{}) -} - -type setOperationInputMiddleware struct { -} - -func (*setOperationInputMiddleware) ID() string { - return "setOperationInput" -} - -func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - ctx = setOperationInput(ctx, in.Parameters) - return next.HandleSerialize(ctx, in) -} - -func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error { - if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil { - return fmt.Errorf("add ResolveAuthScheme: %w", err) - } - if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil { - return fmt.Errorf("add GetIdentity: %v", err) - } - if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil { - return fmt.Errorf("add ResolveEndpointV2: %v", err) - } - if err := stack.Finalize.Insert(&signRequestMiddleware{options: options}, "ResolveEndpointV2", middleware.After); err != nil { - return fmt.Errorf("add Signing: %w", err) - } - return nil -} -func resolveAuthSchemeResolver(options *Options) { - if options.AuthSchemeResolver == nil { - options.AuthSchemeResolver = &defaultAuthSchemeResolver{} - } -} - -func resolveAuthSchemes(options *Options) { - if options.AuthSchemes == nil { - options.AuthSchemes = []smithyhttp.AuthScheme{ - internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{ - Signer: options.HTTPSignerV4, - Logger: options.Logger, - LogSigning: options.ClientLogMode.IsSigning(), - }), - } - } -} - -type noSmithyDocumentSerde = smithydocument.NoSerde - -type legacyEndpointContextSetter struct { - LegacyResolver EndpointResolver -} - -func (*legacyEndpointContextSetter) ID() string { - return "legacyEndpointContextSetter" -} - -func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - if m.LegacyResolver != nil { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) - } - - return next.HandleInitialize(ctx, in) - -} -func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { - return stack.Initialize.Add(&legacyEndpointContextSetter{ - LegacyResolver: o.EndpointResolver, - }, middleware.Before) -} - -func resolveDefaultLogger(o *Options) { - if o.Logger != nil { - return - } - o.Logger = logging.Nop{} -} - -func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { - return middleware.AddSetLoggerMiddleware(stack, o.Logger) -} - -func setResolvedDefaultsMode(o *Options) { - if len(o.resolvedDefaultsMode) > 0 { - return - } - - var mode aws.DefaultsMode - mode.SetFromString(string(o.DefaultsMode)) - - if mode == aws.DefaultsModeAuto { - mode = defaults.ResolveDefaultsModeAuto(o.Region, o.RuntimeEnvironment) - } - - o.resolvedDefaultsMode = mode -} - -// NewFromConfig returns a new client from the provided config. -func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { - opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, - AuthSchemePreference: cfg.AuthSchemePreference, - } - resolveAWSRetryerProvider(cfg, &opts) - resolveAWSRetryMaxAttempts(cfg, &opts) - resolveAWSRetryMode(cfg, &opts) - resolveAWSEndpointResolver(cfg, &opts) - resolveInterceptors(cfg, &opts) - resolveUseDualStackEndpoint(cfg, &opts) - resolveUseFIPSEndpoint(cfg, &opts) - resolveBaseEndpoint(cfg, &opts) - return New(opts, func(o *Options) { - for _, opt := range cfg.ServiceOptions { - opt(ServiceID, o) - } - for _, opt := range optFns { - opt(o) - } - }) -} - -func resolveHTTPClient(o *Options) { - var buildable *awshttp.BuildableClient - - if o.HTTPClient != nil { - var ok bool - buildable, ok = o.HTTPClient.(*awshttp.BuildableClient) - if !ok { - return - } - } else { - buildable = awshttp.NewBuildableClient() - } - - modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) - if err == nil { - buildable = buildable.WithDialerOptions(func(dialer *net.Dialer) { - if dialerTimeout, ok := modeConfig.GetConnectTimeout(); ok { - dialer.Timeout = dialerTimeout - } - }) - - buildable = buildable.WithTransportOptions(func(transport *http.Transport) { - if tlsHandshakeTimeout, ok := modeConfig.GetTLSNegotiationTimeout(); ok { - transport.TLSHandshakeTimeout = tlsHandshakeTimeout - } - }) - } - - o.HTTPClient = buildable -} - -func resolveRetryer(o *Options) { - if o.Retryer != nil { - return - } - - if len(o.RetryMode) == 0 { - modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) - if err == nil { - o.RetryMode = modeConfig.RetryMode - } - } - if len(o.RetryMode) == 0 { - o.RetryMode = aws.RetryModeStandard - } - - var standardOptions []func(*retry.StandardOptions) - if v := o.RetryMaxAttempts; v != 0 { - standardOptions = append(standardOptions, func(so *retry.StandardOptions) { - so.MaxAttempts = v - }) - } - - switch o.RetryMode { - case aws.RetryModeAdaptive: - var adaptiveOptions []func(*retry.AdaptiveModeOptions) - if len(standardOptions) != 0 { - adaptiveOptions = append(adaptiveOptions, func(ao *retry.AdaptiveModeOptions) { - ao.StandardOptions = append(ao.StandardOptions, standardOptions...) - }) - } - o.Retryer = retry.NewAdaptiveMode(adaptiveOptions...) - - default: - o.Retryer = retry.NewStandard(standardOptions...) - } -} - -func resolveAWSRetryerProvider(cfg aws.Config, o *Options) { - if cfg.Retryer == nil { - return - } - o.Retryer = cfg.Retryer() -} - -func resolveAWSRetryMode(cfg aws.Config, o *Options) { - if len(cfg.RetryMode) == 0 { - return - } - o.RetryMode = cfg.RetryMode -} -func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) { - if cfg.RetryMaxAttempts == 0 { - return - } - o.RetryMaxAttempts = cfg.RetryMaxAttempts -} - -func finalizeRetryMaxAttempts(o *Options) { - if o.RetryMaxAttempts == 0 { - return - } - - o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) -} - -func finalizeOperationRetryMaxAttempts(o *Options, client Client) { - if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts { - return - } - - o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) -} - -func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { - if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { - return - } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) -} - -func resolveInterceptors(cfg aws.Config, o *Options) { - o.Interceptors = cfg.Interceptors.Copy() -} - -func addClientUserAgent(stack *middleware.Stack, options Options) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - ua.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "sts", goModuleVersion) - if len(options.AppID) > 0 { - ua.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID) - } - - return nil -} - -func getOrAddRequestUserAgent(stack *middleware.Stack) (*awsmiddleware.RequestUserAgent, error) { - id := (*awsmiddleware.RequestUserAgent)(nil).ID() - mw, ok := stack.Build.Get(id) - if !ok { - mw = awsmiddleware.NewRequestUserAgent() - if err := stack.Build.Add(mw, middleware.After); err != nil { - return nil, err - } - } - - ua, ok := mw.(*awsmiddleware.RequestUserAgent) - if !ok { - return nil, fmt.Errorf("%T for %s middleware did not match expected type", mw, id) - } - - return ua, nil -} - -type HTTPSignerV4 interface { - SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error -} - -func resolveHTTPSignerV4(o *Options) { - if o.HTTPSignerV4 != nil { - return - } - o.HTTPSignerV4 = newDefaultV4Signer(*o) -} - -func newDefaultV4Signer(o Options) *v4.Signer { - return v4.NewSigner(func(so *v4.SignerOptions) { - so.Logger = o.Logger - so.LogSigning = o.ClientLogMode.IsSigning() - }) -} - -func addClientRequestID(stack *middleware.Stack) error { - return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) -} - -func addComputeContentLength(stack *middleware.Stack) error { - return stack.Build.Add(&smithyhttp.ComputeContentLength{}, middleware.After) -} - -func addRawResponseToMetadata(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) -} - -func addRecordResponseTiming(stack *middleware.Stack) error { - return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) -} - -func addSpanRetryLoop(stack *middleware.Stack, options Options) error { - return stack.Finalize.Insert(&spanRetryLoop{options: options}, "Retry", middleware.Before) -} - -type spanRetryLoop struct { - options Options -} - -func (*spanRetryLoop) ID() string { - return "spanRetryLoop" -} - -func (m *spanRetryLoop) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - middleware.FinalizeOutput, middleware.Metadata, error, -) { - tracer := operationTracer(m.options.TracerProvider) - ctx, span := tracer.StartSpan(ctx, "RetryLoop") - defer span.End() - - return next.HandleFinalize(ctx, in) -} -func addStreamingEventsPayload(stack *middleware.Stack) error { - return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before) -} - -func addUnsignedPayload(stack *middleware.Stack) error { - return stack.Finalize.Insert(&v4.UnsignedPayload{}, "ResolveEndpointV2", middleware.After) -} - -func addComputePayloadSHA256(stack *middleware.Stack) error { - return stack.Finalize.Insert(&v4.ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After) -} - -func addContentSHA256Header(stack *middleware.Stack) error { - return stack.Finalize.Insert(&v4.ContentSHA256Header{}, (*v4.ComputePayloadSHA256)(nil).ID(), middleware.After) -} - -func addIsWaiterUserAgent(o *Options) { - o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureWaiter) - return nil - }) -} - -func addIsPaginatorUserAgent(o *Options) { - o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeaturePaginator) - return nil - }) -} - -func addRetry(stack *middleware.Stack, o Options) error { - attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) { - m.LogAttempts = o.ClientLogMode.IsRetries() - m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/sts") - }) - if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { - return err - } - if err := stack.Finalize.Insert(&retry.MetricsHeader{}, attempt.ID(), middleware.After); err != nil { - return err - } - return nil -} - -// resolves dual-stack endpoint configuration -func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error { - if len(cfg.ConfigSources) == 0 { - return nil - } - value, found, err := internalConfig.ResolveUseDualStackEndpoint(context.Background(), cfg.ConfigSources) - if err != nil { - return err - } - if found { - o.EndpointOptions.UseDualStackEndpoint = value - } - return nil -} - -// resolves FIPS endpoint configuration -func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error { - if len(cfg.ConfigSources) == 0 { - return nil - } - value, found, err := internalConfig.ResolveUseFIPSEndpoint(context.Background(), cfg.ConfigSources) - if err != nil { - return err - } - if found { - o.EndpointOptions.UseFIPSEndpoint = value - } - return nil -} - -func resolveAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) *string { - if mode == aws.AccountIDEndpointModeDisabled { - return nil - } - - if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); ok && ca.Credentials.AccountID != "" { - return aws.String(ca.Credentials.AccountID) - } - - return nil -} - -func addTimeOffsetBuild(stack *middleware.Stack, c *Client) error { - mw := internalmiddleware.AddTimeOffsetMiddleware{Offset: c.timeOffset} - if err := stack.Build.Add(&mw, middleware.After); err != nil { - return err - } - return stack.Deserialize.Insert(&mw, "RecordResponseTiming", middleware.Before) -} -func initializeTimeOffsetResolver(c *Client) { - c.timeOffset = new(atomic.Int64) -} - -func addUserAgentRetryMode(stack *middleware.Stack, options Options) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - switch options.Retryer.(type) { - case *retry.Standard: - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeStandard) - case *retry.AdaptiveMode: - ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeAdaptive) - } - return nil -} - -type setCredentialSourceMiddleware struct { - ua *awsmiddleware.RequestUserAgent - options Options -} - -func (m setCredentialSourceMiddleware) ID() string { return "SetCredentialSourceMiddleware" } - -func (m setCredentialSourceMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - asProviderSource, ok := m.options.Credentials.(aws.CredentialProviderSource) - if !ok { - return next.HandleBuild(ctx, in) - } - providerSources := asProviderSource.ProviderSources() - for _, source := range providerSources { - m.ua.AddCredentialsSource(source) - } - return next.HandleBuild(ctx, in) -} - -func addCredentialSource(stack *middleware.Stack, options Options) error { - ua, err := getOrAddRequestUserAgent(stack) - if err != nil { - return err - } - - mw := setCredentialSourceMiddleware{ua: ua, options: options} - return stack.Build.Insert(&mw, "UserAgent", middleware.Before) -} - -func resolveTracerProvider(options *Options) { - if options.TracerProvider == nil { - options.TracerProvider = &tracing.NopTracerProvider{} - } -} - -func resolveMeterProvider(options *Options) { - if options.MeterProvider == nil { - options.MeterProvider = metrics.NopMeterProvider{} - } -} - -func addRecursionDetection(stack *middleware.Stack) error { - return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After) -} - -func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error { - return stack.Deserialize.Insert(&awsmiddleware.RequestIDRetriever{}, "OperationDeserializer", middleware.Before) - -} - -func addResponseErrorMiddleware(stack *middleware.Stack) error { - return stack.Deserialize.Insert(&awshttp.ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before) - -} - -// HTTPPresignerV4 represents presigner interface used by presign url client -type HTTPPresignerV4 interface { - PresignHTTP( - ctx context.Context, credentials aws.Credentials, r *http.Request, - payloadHash string, service string, region string, signingTime time.Time, - optFns ...func(*v4.SignerOptions), - ) (url string, signedHeader http.Header, err error) -} - -// PresignOptions represents the presign client options -type PresignOptions struct { - - // ClientOptions are list of functional options to mutate client options used by - // the presign client. - ClientOptions []func(*Options) - - // Presigner is the presigner used by the presign url client - Presigner HTTPPresignerV4 -} - -func (o PresignOptions) copy() PresignOptions { - clientOptions := make([]func(*Options), len(o.ClientOptions)) - copy(clientOptions, o.ClientOptions) - o.ClientOptions = clientOptions - return o -} - -// WithPresignClientFromClientOptions is a helper utility to retrieve a function -// that takes PresignOption as input -func WithPresignClientFromClientOptions(optFns ...func(*Options)) func(*PresignOptions) { - return withPresignClientFromClientOptions(optFns).options -} - -type withPresignClientFromClientOptions []func(*Options) - -func (w withPresignClientFromClientOptions) options(o *PresignOptions) { - o.ClientOptions = append(o.ClientOptions, w...) -} - -// PresignClient represents the presign url client -type PresignClient struct { - client *Client - options PresignOptions -} - -// NewPresignClient generates a presign client using provided API Client and -// presign options -func NewPresignClient(c *Client, optFns ...func(*PresignOptions)) *PresignClient { - var options PresignOptions - for _, fn := range optFns { - fn(&options) - } - if len(options.ClientOptions) != 0 { - c = New(c.options, options.ClientOptions...) - } - - if options.Presigner == nil { - options.Presigner = newDefaultV4Signer(c.options) - } - - return &PresignClient{ - client: c, - options: options, - } -} - -func withNopHTTPClientAPIOption(o *Options) { - o.HTTPClient = smithyhttp.NopClient{} -} - -type presignContextPolyfillMiddleware struct { -} - -func (*presignContextPolyfillMiddleware) ID() string { - return "presignContextPolyfill" -} - -func (m *presignContextPolyfillMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - schemeID := rscheme.Scheme.SchemeID() - - if schemeID == "aws.auth#sigv4" || schemeID == "com.amazonaws.s3#sigv4express" { - if sn, ok := smithyhttp.GetSigV4SigningName(&rscheme.SignerProperties); ok { - ctx = awsmiddleware.SetSigningName(ctx, sn) - } - if sr, ok := smithyhttp.GetSigV4SigningRegion(&rscheme.SignerProperties); ok { - ctx = awsmiddleware.SetSigningRegion(ctx, sr) - } - } else if schemeID == "aws.auth#sigv4a" { - if sn, ok := smithyhttp.GetSigV4ASigningName(&rscheme.SignerProperties); ok { - ctx = awsmiddleware.SetSigningName(ctx, sn) - } - if sr, ok := smithyhttp.GetSigV4ASigningRegions(&rscheme.SignerProperties); ok { - ctx = awsmiddleware.SetSigningRegion(ctx, sr[0]) - } - } - - return next.HandleFinalize(ctx, in) -} - -type presignConverter PresignOptions - -func (c presignConverter) convertToPresignMiddleware(stack *middleware.Stack, options Options) (err error) { - if _, ok := stack.Finalize.Get((*acceptencodingcust.DisableGzip)(nil).ID()); ok { - stack.Finalize.Remove((*acceptencodingcust.DisableGzip)(nil).ID()) - } - if _, ok := stack.Finalize.Get((*retry.Attempt)(nil).ID()); ok { - stack.Finalize.Remove((*retry.Attempt)(nil).ID()) - } - if _, ok := stack.Finalize.Get((*retry.MetricsHeader)(nil).ID()); ok { - stack.Finalize.Remove((*retry.MetricsHeader)(nil).ID()) - } - stack.Deserialize.Clear() - stack.Build.Remove((*awsmiddleware.ClientRequestID)(nil).ID()) - stack.Build.Remove("UserAgent") - if err := stack.Finalize.Insert(&presignContextPolyfillMiddleware{}, "Signing", middleware.Before); err != nil { - return err - } - - pmw := v4.NewPresignHTTPRequestMiddleware(v4.PresignHTTPRequestMiddlewareOptions{ - CredentialsProvider: options.Credentials, - Presigner: c.Presigner, - LogSigning: options.ClientLogMode.IsSigning(), - }) - if _, err := stack.Finalize.Swap("Signing", pmw); err != nil { - return err - } - if err = smithyhttp.AddNoPayloadDefaultContentTypeRemover(stack); err != nil { - return err - } - // convert request to a GET request - err = query.AddAsGetRequestMiddleware(stack) - if err != nil { - return err - } - err = presignedurlcust.AddAsIsPresigningMiddleware(stack) - if err != nil { - return err - } - return nil -} - -func addRequestResponseLogging(stack *middleware.Stack, o Options) error { - return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{ - LogRequest: o.ClientLogMode.IsRequest(), - LogRequestWithBody: o.ClientLogMode.IsRequestWithBody(), - LogResponse: o.ClientLogMode.IsResponse(), - LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), - }, middleware.After) -} - -type disableHTTPSMiddleware struct { - DisableHTTPS bool -} - -func (*disableHTTPSMiddleware) ID() string { - return "disableHTTPS" -} - -func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { - req.URL.Scheme = "http" - } - - return next.HandleFinalize(ctx, in) -} - -func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { - return stack.Finalize.Insert(&disableHTTPSMiddleware{ - DisableHTTPS: o.EndpointOptions.DisableHTTPS, - }, "ResolveEndpointV2", middleware.After) -} - -func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error { - return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{ - Interceptors: opts.Interceptors.BeforeRetryLoop, - }, "Retry", middleware.Before) -} - -func addInterceptAttempt(stack *middleware.Stack, opts Options) error { - return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{ - BeforeAttempt: opts.Interceptors.BeforeAttempt, - AfterAttempt: opts.Interceptors.AfterAttempt, - }, "Retry", middleware.After) -} - -func addInterceptors(stack *middleware.Stack, opts Options) error { - // middlewares are expensive, don't add all of these interceptor ones unless the caller - // actually has at least one interceptor configured - // - // at the moment it's all-or-nothing because some of the middlewares here are responsible for - // setting fields in the interceptor context for future ones - if len(opts.Interceptors.BeforeExecution) == 0 && - len(opts.Interceptors.BeforeSerialization) == 0 && len(opts.Interceptors.AfterSerialization) == 0 && - len(opts.Interceptors.BeforeRetryLoop) == 0 && - len(opts.Interceptors.BeforeAttempt) == 0 && - len(opts.Interceptors.BeforeSigning) == 0 && len(opts.Interceptors.AfterSigning) == 0 && - len(opts.Interceptors.BeforeTransmit) == 0 && len(opts.Interceptors.AfterTransmit) == 0 && - len(opts.Interceptors.BeforeDeserialization) == 0 && len(opts.Interceptors.AfterDeserialization) == 0 && - len(opts.Interceptors.AfterAttempt) == 0 && len(opts.Interceptors.AfterExecution) == 0 { - return nil - } - - return errors.Join( - stack.Initialize.Add(&smithyhttp.InterceptExecution{ - BeforeExecution: opts.Interceptors.BeforeExecution, - AfterExecution: opts.Interceptors.AfterExecution, - }, middleware.Before), - stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{ - Interceptors: opts.Interceptors.BeforeSerialization, - }, "OperationSerializer", middleware.Before), - stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{ - Interceptors: opts.Interceptors.AfterSerialization, - }, "OperationSerializer", middleware.After), - stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{ - Interceptors: opts.Interceptors.BeforeSigning, - }, "Signing", middleware.Before), - stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{ - Interceptors: opts.Interceptors.AfterSigning, - }, "Signing", middleware.After), - stack.Deserialize.Add(&smithyhttp.InterceptTransmit{ - BeforeTransmit: opts.Interceptors.BeforeTransmit, - AfterTransmit: opts.Interceptors.AfterTransmit, - }, middleware.After), - stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{ - Interceptors: opts.Interceptors.BeforeDeserialization, - }, "OperationDeserializer", middleware.After), // (deserialize stack is called in reverse) - stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{ - Interceptors: opts.Interceptors.AfterDeserialization, - }, "OperationDeserializer", middleware.Before), - ) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go deleted file mode 100644 index 0ddd362..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go +++ /dev/null @@ -1,547 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a set of temporary security credentials that you can use to access -// Amazon Web Services resources. These temporary credentials consist of an access -// key ID, a secret access key, and a security token. Typically, you use AssumeRole -// within your account or for cross-account access. For a comparison of AssumeRole -// with other API operations that produce temporary credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the -// IAM User Guide. -// -// # Permissions -// -// The temporary security credentials created by AssumeRole can be used to make -// API calls to any Amazon Web Services service with the following exception: You -// cannot call the Amazon Web Services STS GetFederationToken or GetSessionToken -// API operations. -// -// (Optional) You can pass inline or managed session policies to this operation. -// You can pass a single JSON policy document to use as an inline session policy. -// You can also specify up to 10 managed policy Amazon Resource Names (ARNs) to use -// as managed session policies. The plaintext that you use for both inline and -// managed session policies can't exceed 2,048 characters. Passing policies to this -// operation returns new temporary credentials. The resulting session's permissions -// are the intersection of the role's identity-based policy and the session -// policies. You can use the role's temporary credentials in subsequent Amazon Web -// Services API calls to access resources in the account that owns the role. You -// cannot use session policies to grant more permissions than those allowed by the -// identity-based policy of the role that is being assumed. For more information, -// see [Session Policies]in the IAM User Guide. -// -// When you create a role, you create two policies: a role trust policy that -// specifies who can assume the role, and a permissions policy that specifies what -// can be done with the role. You specify the trusted principal that is allowed to -// assume the role in the role trust policy. -// -// To assume a role from a different account, your Amazon Web Services account -// must be trusted by the role. The trust relationship is defined in the role's -// trust policy when the role is created. That trust policy states which accounts -// are allowed to delegate that access to users in the account. -// -// A user who wants to access a role in a different account must also have -// permissions that are delegated from the account administrator. The administrator -// must attach a policy that allows the user to call AssumeRole for the ARN of the -// role in the other account. -// -// To allow a user to assume a role in the same account, you can do either of the -// following: -// -// - Attach a policy to the user that allows the user to call AssumeRole (as long -// as the role's trust policy trusts the account). -// -// - Add the user as a principal directly in the role's trust policy. -// -// You can do either because the role’s trust policy acts as an IAM resource-based -// policy. When a resource-based policy grants access to a principal in the same -// account, no additional identity-based policy is required. For more information -// about trust policies and resource-based policies, see [IAM Policies]in the IAM User Guide. -// -// # Tags -// -// (Optional) You can pass tag key-value pairs to your session. These tags are -// called session tags. For more information about session tags, see [Passing Session Tags in STS]in the IAM -// User Guide. -// -// An administrator must grant you the permissions necessary to pass session tags. -// The administrator can also create granular permissions to allow you to pass only -// specific session tags. For more information, see [Tutorial: Using Tags for Attribute-Based Access Control]in the IAM User Guide. -// -// You can set the session tags as transitive. Transitive tags persist during role -// chaining. For more information, see [Chaining Roles with Session Tags]in the IAM User Guide. -// -// # Using MFA with AssumeRole -// -// (Optional) You can include multi-factor authentication (MFA) information when -// you call AssumeRole . This is useful for cross-account scenarios to ensure that -// the user that assumes the role has been authenticated with an Amazon Web -// Services MFA device. In that scenario, the trust policy of the role being -// assumed includes a condition that tests for MFA authentication. If the caller -// does not include valid MFA information, the request to assume the role is -// denied. The condition in a trust policy that tests for MFA authentication might -// look like the following example. -// -// "Condition": {"Bool": {"aws:MultiFactorAuthPresent": true}} -// -// For more information, see [Configuring MFA-Protected API Access] in the IAM User Guide guide. -// -// To use MFA with AssumeRole , you pass values for the SerialNumber and TokenCode -// parameters. The SerialNumber value identifies the user's hardware or virtual -// MFA device. The TokenCode is the time-based one-time password (TOTP) that the -// MFA device produces. -// -// [Configuring MFA-Protected API Access]: https://docs.aws.amazon.com/IAM/latest/UserGuide/MFAProtectedAPI.html -// [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session -// [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html -// [Chaining Roles with Session Tags]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining -// [IAM Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html -// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html -// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html -// [Tutorial: Using Tags for Attribute-Based Access Control]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html -func (c *Client) AssumeRole(ctx context.Context, params *AssumeRoleInput, optFns ...func(*Options)) (*AssumeRoleOutput, error) { - if params == nil { - params = &AssumeRoleInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "AssumeRole", params, optFns, c.addOperationAssumeRoleMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*AssumeRoleOutput) - out.ResultMetadata = metadata - return out, nil -} - -type AssumeRoleInput struct { - - // The Amazon Resource Name (ARN) of the role to assume. - // - // This member is required. - RoleArn *string - - // An identifier for the assumed role session. - // - // Use the role session name to uniquely identify a session when the same role is - // assumed by different principals or for different reasons. In cross-account - // scenarios, the role session name is visible to, and can be logged by the account - // that owns the role. The role session name is also used in the ARN of the assumed - // role principal. This means that subsequent cross-account API requests that use - // the temporary security credentials will expose the role session name to the - // external account in their CloudTrail logs. - // - // For security purposes, administrators can view this field in [CloudTrail logs] to help identify - // who performed an action in Amazon Web Services. Your administrator might require - // that you specify your user name as the session name when you assume the role. - // For more information, see [sts:RoleSessionName]sts:RoleSessionName . - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: +=,.@- - // - // [CloudTrail logs]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html#cloudtrail-integration_signin-tempcreds - // [sts:RoleSessionName]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#ck_rolesessionname - // - // This member is required. - RoleSessionName *string - - // The duration, in seconds, of the role session. The value specified can range - // from 900 seconds (15 minutes) up to the maximum session duration set for the - // role. The maximum session duration setting can have a value from 1 hour to 12 - // hours. If you specify a value higher than this setting or the administrator - // setting (whichever is lower), the operation fails. For example, if you specify a - // session duration of 12 hours, but your administrator set the maximum session - // duration to 6 hours, your operation fails. - // - // Role chaining limits your Amazon Web Services CLI or Amazon Web Services API - // role session to a maximum of one hour. When you use the AssumeRole API - // operation to assume a role, you can specify the duration of your role session - // with the DurationSeconds parameter. You can specify a parameter value of up to - // 43200 seconds (12 hours), depending on the maximum session duration setting for - // your role. However, if you assume a role using role chaining and provide a - // DurationSeconds parameter value greater than one hour, the operation fails. To - // learn how to view the maximum value for your role, see [Update the maximum session duration for a role]. - // - // By default, the value is set to 3600 seconds. - // - // The DurationSeconds parameter is separate from the duration of a console - // session that you might request using the returned credentials. The request to - // the federation endpoint for a console sign-in token takes a SessionDuration - // parameter that specifies the maximum length of the console session. For more - // information, see [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]in the IAM User Guide. - // - // [Update the maximum session duration for a role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-settings.html#id_roles_update-session-duration - // [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html - DurationSeconds *int32 - - // A unique identifier that might be required when you assume a role in another - // account. If the administrator of the account to which the role belongs provided - // you with an external ID, then provide that value in the ExternalId parameter. - // This value can be any string, such as a passphrase or account number. A - // cross-account role is usually set up to trust everyone in an account. Therefore, - // the administrator of the trusting account might send an external ID to the - // administrator of the trusted account. That way, only someone with the ID can - // assume the role, rather than everyone in the account. For more information about - // the external ID, see [How to Use an External ID When Granting Access to Your Amazon Web Services Resources to a Third Party]in the IAM User Guide. - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: +=,.@:\/- - // - // [How to Use an External ID When Granting Access to Your Amazon Web Services Resources to a Third Party]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html - ExternalId *string - - // An IAM policy in JSON format that you want to use as an inline session policy. - // - // This parameter is optional. Passing policies to this operation returns new - // temporary credentials. The resulting session's permissions are the intersection - // of the role's identity-based policy and the session policies. You can use the - // role's temporary credentials in subsequent Amazon Web Services API calls to - // access resources in the account that owns the role. You cannot use session - // policies to grant more permissions than those allowed by the identity-based - // policy of the role that is being assumed. For more information, see [Session Policies]in the IAM - // User Guide. - // - // The plaintext that you use for both inline and managed session policies can't - // exceed 2,048 characters. The JSON policy characters can be any ASCII character - // from the space character to the end of the valid character list (\u0020 through - // \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage - // return (\u000D) characters. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // For more information about role session permissions, see [Session policies]. - // - // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - // [Session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - Policy *string - - // The Amazon Resource Names (ARNs) of the IAM managed policies that you want to - // use as managed session policies. The policies must exist in the same account as - // the role. - // - // This parameter is optional. You can provide up to 10 managed policy ARNs. - // However, the plaintext that you use for both inline and managed session policies - // can't exceed 2,048 characters. For more information about ARNs, see [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]in the - // Amazon Web Services General Reference. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // Passing policies to this operation returns new temporary credentials. The - // resulting session's permissions are the intersection of the role's - // identity-based policy and the session policies. You can use the role's temporary - // credentials in subsequent Amazon Web Services API calls to access resources in - // the account that owns the role. You cannot use session policies to grant more - // permissions than those allowed by the identity-based policy of the role that is - // being assumed. For more information, see [Session Policies]in the IAM User Guide. - // - // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - // [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html - PolicyArns []types.PolicyDescriptorType - - // A list of previously acquired trusted context assertions in the format of a - // JSON array. The trusted context assertion is signed and encrypted by Amazon Web - // Services STS. - // - // The following is an example of a ProvidedContext value that includes a single - // trusted context assertion and the ARN of the context provider from which the - // trusted context assertion was generated. - // - // [{"ProviderArn":"arn:aws:iam::aws:contextProvider/IdentityCenter","ContextAssertion":"trusted-context-assertion"}] - ProvidedContexts []types.ProvidedContext - - // The identification number of the MFA device that is associated with the user - // who is making the AssumeRole call. Specify this value if the trust policy of - // the role being assumed includes a condition that requires MFA authentication. - // The value is either the serial number for a hardware device (such as - // GAHT12345678 ) or an Amazon Resource Name (ARN) for a virtual device (such as - // arn:aws:iam::123456789012:mfa/user ). - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: +=/:,.@- - SerialNumber *string - - // The source identity specified by the principal that is calling the AssumeRole - // operation. The source identity value persists across [chained role]sessions. - // - // You can require users to specify a source identity when they assume a role. You - // do this by using the [sts:SourceIdentity]sts:SourceIdentity condition key in a role trust policy. - // You can use source identity information in CloudTrail logs to determine who took - // actions with a role. You can use the aws:SourceIdentity condition key to - // further control access to Amazon Web Services resources based on the value of - // source identity. For more information about using source identity, see [Monitor and control actions taken with assumed roles]in the - // IAM User Guide. - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: +=,.@-. You cannot use a - // value that begins with the text aws: . This prefix is reserved for Amazon Web - // Services internal use. - // - // [chained role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#iam-term-role-chaining - // [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html - // [sts:SourceIdentity]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceidentity - SourceIdentity *string - - // A list of session tags that you want to pass. Each session tag consists of a - // key name and an associated value. For more information about session tags, see [Tagging Amazon Web Services STS Sessions] - // in the IAM User Guide. - // - // This parameter is optional. You can pass up to 50 session tags. The plaintext - // session tag keys can’t exceed 128 characters, and the values can’t exceed 256 - // characters. For these and additional limits, see [IAM and STS Character Limits]in the IAM User Guide. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // You can pass a session tag with the same key as a tag that is already attached - // to the role. When you do, session tags override a role tag with the same key. - // - // Tag key–value pairs are not case sensitive, but case is preserved. This means - // that you cannot have separate Department and department tag keys. Assume that - // the role has the Department = Marketing tag and you pass the department = - // engineering session tag. Department and department are not saved as separate - // tags, and the session tag passed in the request takes precedence over the role - // tag. - // - // Additionally, if you used temporary credentials to perform this operation, the - // new session inherits any transitive session tags from the calling session. If - // you pass a session tag with the same key as an inherited tag, the operation - // fails. To view the inherited tags for a session, see the CloudTrail logs. For - // more information, see [Viewing Session Tags in CloudTrail]in the IAM User Guide. - // - // [Tagging Amazon Web Services STS Sessions]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html - // [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length - // [Viewing Session Tags in CloudTrail]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_ctlogs - Tags []types.Tag - - // The value provided by the MFA device, if the trust policy of the role being - // assumed requires MFA. (In other words, if the policy includes a condition that - // tests for MFA). If the role being assumed requires MFA and if the TokenCode - // value is missing or expired, the AssumeRole call returns an "access denied" - // error. - // - // The format for this parameter, as described by its regex pattern, is a sequence - // of six numeric digits. - TokenCode *string - - // A list of keys for session tags that you want to set as transitive. If you set - // a tag key as transitive, the corresponding key and value passes to subsequent - // sessions in a role chain. For more information, see [Chaining Roles with Session Tags]in the IAM User Guide. - // - // This parameter is optional. The transitive status of a session tag does not - // impact its packed binary size. - // - // If you choose not to specify a transitive tag key, then no tags are passed from - // this session to any subsequent sessions. - // - // [Chaining Roles with Session Tags]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining - TransitiveTagKeys []string - - noSmithyDocumentSerde -} - -// Contains the response to a successful AssumeRole request, including temporary Amazon Web -// Services credentials that can be used to make Amazon Web Services requests. -type AssumeRoleOutput struct { - - // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers - // that you can use to refer to the resulting temporary security credentials. For - // example, you can reference these credentials as a principal in a resource-based - // policy by using the ARN or assumed role ID. The ARN and ID include the - // RoleSessionName that you specified when you called AssumeRole . - AssumedRoleUser *types.AssumedRoleUser - - // The temporary security credentials, which include an access key ID, a secret - // access key, and a security (or session) token. - // - // The size of the security token that STS API operations return is not fixed. We - // strongly recommend that you make no assumptions about the maximum size. - Credentials *types.Credentials - - // A percentage value that indicates the packed size of the session policies and - // session tags combined passed in the request. The request fails if the packed - // size is greater than 100 percent, which means the policies and tags exceeded the - // allowed space. - PackedPolicySize *int32 - - // The source identity specified by the principal that is calling the AssumeRole - // operation. - // - // You can require users to specify a source identity when they assume a role. You - // do this by using the sts:SourceIdentity condition key in a role trust policy. - // You can use source identity information in CloudTrail logs to determine who took - // actions with a role. You can use the aws:SourceIdentity condition key to - // further control access to Amazon Web Services resources based on the value of - // source identity. For more information about using source identity, see [Monitor and control actions taken with assumed roles]in the - // IAM User Guide. - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- - // - // [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html - SourceIdentity *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpAssumeRole{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpAssumeRole{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "AssumeRole"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = addOpAssumeRoleValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opAssumeRole(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opAssumeRole(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "AssumeRole", - } -} - -// PresignAssumeRole is used to generate a presigned HTTP Request which contains -// presigned URL, signed headers and HTTP method used. -func (c *PresignClient) PresignAssumeRole(ctx context.Context, params *AssumeRoleInput, optFns ...func(*PresignOptions)) (*v4.PresignedHTTPRequest, error) { - if params == nil { - params = &AssumeRoleInput{} - } - options := c.options.copy() - for _, fn := range optFns { - fn(&options) - } - clientOptFns := append(options.ClientOptions, withNopHTTPClientAPIOption) - - result, _, err := c.client.invokeOperation(ctx, "AssumeRole", params, clientOptFns, - c.client.addOperationAssumeRoleMiddlewares, - presignConverter(options).convertToPresignMiddleware, - ) - if err != nil { - return nil, err - } - - out := result.(*v4.PresignedHTTPRequest) - return out, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go deleted file mode 100644 index 15f1dd9..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go +++ /dev/null @@ -1,458 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a set of temporary security credentials for users who have been -// authenticated via a SAML authentication response. This operation provides a -// mechanism for tying an enterprise identity store or directory to role-based -// Amazon Web Services access without user-specific credentials or configuration. -// For a comparison of AssumeRoleWithSAML with the other API operations that -// produce temporary credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the IAM User Guide. -// -// The temporary security credentials returned by this operation consist of an -// access key ID, a secret access key, and a security token. Applications can use -// these temporary security credentials to sign calls to Amazon Web Services -// services. -// -// AssumeRoleWithSAML will not work on IAM Identity Center managed roles. These -// roles' names start with AWSReservedSSO_ . -// -// # Session Duration -// -// By default, the temporary security credentials created by AssumeRoleWithSAML -// last for one hour. However, you can use the optional DurationSeconds parameter -// to specify the duration of your session. Your role session lasts for the -// duration that you specify, or until the time specified in the SAML -// authentication response's SessionNotOnOrAfter value, whichever is shorter. You -// can provide a DurationSeconds value from 900 seconds (15 minutes) up to the -// maximum session duration setting for the role. This setting can have a value -// from 1 hour to 12 hours. To learn how to view the maximum value for your role, -// see [View the Maximum Session Duration Setting for a Role]in the IAM User Guide. The maximum session duration limit applies when you -// use the AssumeRole* API operations or the assume-role* CLI commands. However -// the limit does not apply when you use those operations to create a console URL. -// For more information, see [Using IAM Roles]in the IAM User Guide. -// -// [Role chaining]limits your CLI or Amazon Web Services API role session to a maximum of one -// hour. When you use the AssumeRole API operation to assume a role, you can -// specify the duration of your role session with the DurationSeconds parameter. -// You can specify a parameter value of up to 43200 seconds (12 hours), depending -// on the maximum session duration setting for your role. However, if you assume a -// role using role chaining and provide a DurationSeconds parameter value greater -// than one hour, the operation fails. -// -// # Permissions -// -// The temporary security credentials created by AssumeRoleWithSAML can be used to -// make API calls to any Amazon Web Services service with the following exception: -// you cannot call the STS GetFederationToken or GetSessionToken API operations. -// -// (Optional) You can pass inline or managed [session policies] to this operation. You can pass a -// single JSON policy document to use as an inline session policy. You can also -// specify up to 10 managed policy Amazon Resource Names (ARNs) to use as managed -// session policies. The plaintext that you use for both inline and managed session -// policies can't exceed 2,048 characters. Passing policies to this operation -// returns new temporary credentials. The resulting session's permissions are the -// intersection of the role's identity-based policy and the session policies. You -// can use the role's temporary credentials in subsequent Amazon Web Services API -// calls to access resources in the account that owns the role. You cannot use -// session policies to grant more permissions than those allowed by the -// identity-based policy of the role that is being assumed. For more information, -// see [Session Policies]in the IAM User Guide. -// -// Calling AssumeRoleWithSAML does not require the use of Amazon Web Services -// security credentials. The identity of the caller is validated by using keys in -// the metadata document that is uploaded for the SAML provider entity for your -// identity provider. -// -// Calling AssumeRoleWithSAML can result in an entry in your CloudTrail logs. The -// entry includes the value in the NameID element of the SAML assertion. We -// recommend that you use a NameIDType that is not associated with any personally -// identifiable information (PII). For example, you could instead use the -// persistent identifier ( urn:oasis:names:tc:SAML:2.0:nameid-format:persistent ). -// -// # Tags -// -// (Optional) You can configure your IdP to pass attributes into your SAML -// assertion as session tags. Each session tag consists of a key name and an -// associated value. For more information about session tags, see [Passing Session Tags in STS]in the IAM User -// Guide. -// -// You can pass up to 50 session tags. The plaintext session tag keys can’t exceed -// 128 characters and the values can’t exceed 256 characters. For these and -// additional limits, see [IAM and STS Character Limits]in the IAM User Guide. -// -// An Amazon Web Services conversion compresses the passed inline session policy, -// managed policy ARNs, and session tags into a packed binary format that has a -// separate limit. Your request can fail for this limit even if your plaintext -// meets the other requirements. The PackedPolicySize response element indicates -// by percentage how close the policies and tags for your request are to the upper -// size limit. -// -// You can pass a session tag with the same key as a tag that is attached to the -// role. When you do, session tags override the role's tags with the same key. -// -// An administrator must grant you the permissions necessary to pass session tags. -// The administrator can also create granular permissions to allow you to pass only -// specific session tags. For more information, see [Tutorial: Using Tags for Attribute-Based Access Control]in the IAM User Guide. -// -// You can set the session tags as transitive. Transitive tags persist during role -// chaining. For more information, see [Chaining Roles with Session Tags]in the IAM User Guide. -// -// # SAML Configuration -// -// Before your application can call AssumeRoleWithSAML , you must configure your -// SAML identity provider (IdP) to issue the claims required by Amazon Web -// Services. Additionally, you must use Identity and Access Management (IAM) to -// create a SAML provider entity in your Amazon Web Services account that -// represents your identity provider. You must also create an IAM role that -// specifies this SAML provider in its trust policy. -// -// For more information, see the following resources: -// -// [About SAML 2.0-based Federation] -// - in the IAM User Guide. -// -// [Creating SAML Identity Providers] -// - in the IAM User Guide. -// -// [Configuring a Relying Party and Claims] -// - in the IAM User Guide. -// -// [Creating a Role for SAML 2.0 Federation] -// - in the IAM User Guide. -// -// [View the Maximum Session Duration Setting for a Role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session -// [Creating a Role for SAML 2.0 Federation]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html -// [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length -// [Creating SAML Identity Providers]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html -// [session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session -// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html -// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html -// [Tutorial: Using Tags for Attribute-Based Access Control]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html -// [Configuring a Relying Party and Claims]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html -// [Role chaining]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-chaining -// [Using IAM Roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html -// [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session -// [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html -// [About SAML 2.0-based Federation]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html -// [Chaining Roles with Session Tags]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining -func (c *Client) AssumeRoleWithSAML(ctx context.Context, params *AssumeRoleWithSAMLInput, optFns ...func(*Options)) (*AssumeRoleWithSAMLOutput, error) { - if params == nil { - params = &AssumeRoleWithSAMLInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "AssumeRoleWithSAML", params, optFns, c.addOperationAssumeRoleWithSAMLMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*AssumeRoleWithSAMLOutput) - out.ResultMetadata = metadata - return out, nil -} - -type AssumeRoleWithSAMLInput struct { - - // The Amazon Resource Name (ARN) of the SAML provider in IAM that describes the - // IdP. - // - // This member is required. - PrincipalArn *string - - // The Amazon Resource Name (ARN) of the role that the caller is assuming. - // - // This member is required. - RoleArn *string - - // The base64 encoded SAML authentication response provided by the IdP. - // - // For more information, see [Configuring a Relying Party and Adding Claims] in the IAM User Guide. - // - // [Configuring a Relying Party and Adding Claims]: https://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html - // - // This member is required. - SAMLAssertion *string - - // The duration, in seconds, of the role session. Your role session lasts for the - // duration that you specify for the DurationSeconds parameter, or until the time - // specified in the SAML authentication response's SessionNotOnOrAfter value, - // whichever is shorter. You can provide a DurationSeconds value from 900 seconds - // (15 minutes) up to the maximum session duration setting for the role. This - // setting can have a value from 1 hour to 12 hours. If you specify a value higher - // than this setting, the operation fails. For example, if you specify a session - // duration of 12 hours, but your administrator set the maximum session duration to - // 6 hours, your operation fails. To learn how to view the maximum value for your - // role, see [View the Maximum Session Duration Setting for a Role]in the IAM User Guide. - // - // By default, the value is set to 3600 seconds. - // - // The DurationSeconds parameter is separate from the duration of a console - // session that you might request using the returned credentials. The request to - // the federation endpoint for a console sign-in token takes a SessionDuration - // parameter that specifies the maximum length of the console session. For more - // information, see [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]in the IAM User Guide. - // - // [View the Maximum Session Duration Setting for a Role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session - // [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html - DurationSeconds *int32 - - // An IAM policy in JSON format that you want to use as an inline session policy. - // - // This parameter is optional. Passing policies to this operation returns new - // temporary credentials. The resulting session's permissions are the intersection - // of the role's identity-based policy and the session policies. You can use the - // role's temporary credentials in subsequent Amazon Web Services API calls to - // access resources in the account that owns the role. You cannot use session - // policies to grant more permissions than those allowed by the identity-based - // policy of the role that is being assumed. For more information, see [Session Policies]in the IAM - // User Guide. - // - // The plaintext that you use for both inline and managed session policies can't - // exceed 2,048 characters. The JSON policy characters can be any ASCII character - // from the space character to the end of the valid character list (\u0020 through - // \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage - // return (\u000D) characters. - // - // For more information about role session permissions, see [Session policies]. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - // [Session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - Policy *string - - // The Amazon Resource Names (ARNs) of the IAM managed policies that you want to - // use as managed session policies. The policies must exist in the same account as - // the role. - // - // This parameter is optional. You can provide up to 10 managed policy ARNs. - // However, the plaintext that you use for both inline and managed session policies - // can't exceed 2,048 characters. For more information about ARNs, see [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]in the - // Amazon Web Services General Reference. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // Passing policies to this operation returns new temporary credentials. The - // resulting session's permissions are the intersection of the role's - // identity-based policy and the session policies. You can use the role's temporary - // credentials in subsequent Amazon Web Services API calls to access resources in - // the account that owns the role. You cannot use session policies to grant more - // permissions than those allowed by the identity-based policy of the role that is - // being assumed. For more information, see [Session Policies]in the IAM User Guide. - // - // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - // [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html - PolicyArns []types.PolicyDescriptorType - - noSmithyDocumentSerde -} - -// Contains the response to a successful AssumeRoleWithSAML request, including temporary Amazon Web -// Services credentials that can be used to make Amazon Web Services requests. -type AssumeRoleWithSAMLOutput struct { - - // The identifiers for the temporary security credentials that the operation - // returns. - AssumedRoleUser *types.AssumedRoleUser - - // The value of the Recipient attribute of the SubjectConfirmationData element of - // the SAML assertion. - Audience *string - - // The temporary security credentials, which include an access key ID, a secret - // access key, and a security (or session) token. - // - // The size of the security token that STS API operations return is not fixed. We - // strongly recommend that you make no assumptions about the maximum size. - Credentials *types.Credentials - - // The value of the Issuer element of the SAML assertion. - Issuer *string - - // A hash value based on the concatenation of the following: - // - // - The Issuer response value. - // - // - The Amazon Web Services account ID. - // - // - The friendly name (the last part of the ARN) of the SAML provider in IAM. - // - // The combination of NameQualifier and Subject can be used to uniquely identify a - // user. - // - // The following pseudocode shows how the hash value is calculated: - // - // BASE64 ( SHA1 ( "https://example.com/saml" + "123456789012" + "/MySAMLIdP" ) ) - NameQualifier *string - - // A percentage value that indicates the packed size of the session policies and - // session tags combined passed in the request. The request fails if the packed - // size is greater than 100 percent, which means the policies and tags exceeded the - // allowed space. - PackedPolicySize *int32 - - // The value in the SourceIdentity attribute in the SAML assertion. The source - // identity value persists across [chained role]sessions. - // - // You can require users to set a source identity value when they assume a role. - // You do this by using the sts:SourceIdentity condition key in a role trust - // policy. That way, actions that are taken with the role are associated with that - // user. After the source identity is set, the value cannot be changed. It is - // present in the request for all actions that are taken by the role and persists - // across [chained role]sessions. You can configure your SAML identity provider to use an - // attribute associated with your users, like user name or email, as the source - // identity when calling AssumeRoleWithSAML . You do this by adding an attribute to - // the SAML assertion. For more information about using source identity, see [Monitor and control actions taken with assumed roles]in - // the IAM User Guide. - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- - // - // [chained role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#id_roles_terms-and-concepts - // [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html - SourceIdentity *string - - // The value of the NameID element in the Subject element of the SAML assertion. - Subject *string - - // The format of the name ID, as defined by the Format attribute in the NameID - // element of the SAML assertion. Typical examples of the format are transient or - // persistent . - // - // If the format includes the prefix urn:oasis:names:tc:SAML:2.0:nameid-format , - // that prefix is removed. For example, - // urn:oasis:names:tc:SAML:2.0:nameid-format:transient is returned as transient . - // If the format includes any other prefix, the format is returned with no - // modifications. - SubjectType *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpAssumeRoleWithSAML{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpAssumeRoleWithSAML{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "AssumeRoleWithSAML"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = addOpAssumeRoleWithSAMLValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opAssumeRoleWithSAML(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opAssumeRoleWithSAML(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "AssumeRoleWithSAML", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go deleted file mode 100644 index 7006eb3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go +++ /dev/null @@ -1,475 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a set of temporary security credentials for users who have been -// authenticated in a mobile or web application with a web identity provider. -// Example providers include the OAuth 2.0 providers Login with Amazon and -// Facebook, or any OpenID Connect-compatible identity provider such as Google or [Amazon Cognito federated identities]. -// -// For mobile applications, we recommend that you use Amazon Cognito. You can use -// Amazon Cognito with the [Amazon Web Services SDK for iOS Developer Guide]and the [Amazon Web Services SDK for Android Developer Guide] to uniquely identify a user. You can also -// supply the user with a consistent identity throughout the lifetime of an -// application. -// -// To learn more about Amazon Cognito, see [Amazon Cognito identity pools] in Amazon Cognito Developer Guide. -// -// Calling AssumeRoleWithWebIdentity does not require the use of Amazon Web -// Services security credentials. Therefore, you can distribute an application (for -// example, on mobile devices) that requests temporary security credentials without -// including long-term Amazon Web Services credentials in the application. You also -// don't need to deploy server-based proxy services that use long-term Amazon Web -// Services credentials. Instead, the identity of the caller is validated by using -// a token from the web identity provider. For a comparison of -// AssumeRoleWithWebIdentity with the other API operations that produce temporary -// credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the IAM User Guide. -// -// The temporary security credentials returned by this API consist of an access -// key ID, a secret access key, and a security token. Applications can use these -// temporary security credentials to sign calls to Amazon Web Services service API -// operations. -// -// # Session Duration -// -// By default, the temporary security credentials created by -// AssumeRoleWithWebIdentity last for one hour. However, you can use the optional -// DurationSeconds parameter to specify the duration of your session. You can -// provide a value from 900 seconds (15 minutes) up to the maximum session duration -// setting for the role. This setting can have a value from 1 hour to 12 hours. To -// learn how to view the maximum value for your role, see [Update the maximum session duration for a role]in the IAM User Guide. -// The maximum session duration limit applies when you use the AssumeRole* API -// operations or the assume-role* CLI commands. However the limit does not apply -// when you use those operations to create a console URL. For more information, see -// [Using IAM Roles]in the IAM User Guide. -// -// # Permissions -// -// The temporary security credentials created by AssumeRoleWithWebIdentity can be -// used to make API calls to any Amazon Web Services service with the following -// exception: you cannot call the STS GetFederationToken or GetSessionToken API -// operations. -// -// (Optional) You can pass inline or managed [session policies] to this operation. You can pass a -// single JSON policy document to use as an inline session policy. You can also -// specify up to 10 managed policy Amazon Resource Names (ARNs) to use as managed -// session policies. The plaintext that you use for both inline and managed session -// policies can't exceed 2,048 characters. Passing policies to this operation -// returns new temporary credentials. The resulting session's permissions are the -// intersection of the role's identity-based policy and the session policies. You -// can use the role's temporary credentials in subsequent Amazon Web Services API -// calls to access resources in the account that owns the role. You cannot use -// session policies to grant more permissions than those allowed by the -// identity-based policy of the role that is being assumed. For more information, -// see [Session Policies]in the IAM User Guide. -// -// # Tags -// -// (Optional) You can configure your IdP to pass attributes into your web identity -// token as session tags. Each session tag consists of a key name and an associated -// value. For more information about session tags, see [Passing session tags using AssumeRoleWithWebIdentity]in the IAM User Guide. -// -// You can pass up to 50 session tags. The plaintext session tag keys can’t exceed -// 128 characters and the values can’t exceed 256 characters. For these and -// additional limits, see [IAM and STS Character Limits]in the IAM User Guide. -// -// An Amazon Web Services conversion compresses the passed inline session policy, -// managed policy ARNs, and session tags into a packed binary format that has a -// separate limit. Your request can fail for this limit even if your plaintext -// meets the other requirements. The PackedPolicySize response element indicates -// by percentage how close the policies and tags for your request are to the upper -// size limit. -// -// You can pass a session tag with the same key as a tag that is attached to the -// role. When you do, the session tag overrides the role tag with the same key. -// -// An administrator must grant you the permissions necessary to pass session tags. -// The administrator can also create granular permissions to allow you to pass only -// specific session tags. For more information, see [Tutorial: Using Tags for Attribute-Based Access Control]in the IAM User Guide. -// -// You can set the session tags as transitive. Transitive tags persist during role -// chaining. For more information, see [Chaining Roles with Session Tags]in the IAM User Guide. -// -// # Identities -// -// Before your application can call AssumeRoleWithWebIdentity , you must have an -// identity token from a supported identity provider and create a role that the -// application can assume. The role that your application assumes must trust the -// identity provider that is associated with the identity token. In other words, -// the identity provider must be specified in the role's trust policy. -// -// Calling AssumeRoleWithWebIdentity can result in an entry in your CloudTrail -// logs. The entry includes the [Subject]of the provided web identity token. We recommend -// that you avoid using any personally identifiable information (PII) in this -// field. For example, you could instead use a GUID or a pairwise identifier, as [suggested in the OIDC specification]. -// -// For more information about how to use OIDC federation and the -// AssumeRoleWithWebIdentity API, see the following resources: -// -// [Using Web Identity Federation API Operations for Mobile Apps] -// - and [Federation Through a Web-based Identity Provider]. -// -// [Amazon Web Services SDK for iOS Developer Guide] -// - and [Amazon Web Services SDK for Android Developer Guide]. These toolkits contain sample apps that show how to invoke the -// identity providers. The toolkits then show how to use the information from these -// providers to get and use temporary security credentials. -// -// [Amazon Web Services SDK for iOS Developer Guide]: http://aws.amazon.com/sdkforios/ -// [Passing session tags using AssumeRoleWithWebIdentity]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_adding-assume-role-idp -// [Amazon Web Services SDK for Android Developer Guide]: http://aws.amazon.com/sdkforandroid/ -// [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length -// [session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session -// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html -// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html -// [Subject]: http://openid.net/specs/openid-connect-core-1_0.html#Claims -// [Tutorial: Using Tags for Attribute-Based Access Control]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html -// [Amazon Cognito identity pools]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html -// [Federation Through a Web-based Identity Provider]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity -// [Using IAM Roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html -// [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session -// [Amazon Cognito federated identities]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html -// [Chaining Roles with Session Tags]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining -// [Update the maximum session duration for a role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-settings.html#id_roles_update-session-duration -// [Using Web Identity Federation API Operations for Mobile Apps]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html -// [suggested in the OIDC specification]: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes -func (c *Client) AssumeRoleWithWebIdentity(ctx context.Context, params *AssumeRoleWithWebIdentityInput, optFns ...func(*Options)) (*AssumeRoleWithWebIdentityOutput, error) { - if params == nil { - params = &AssumeRoleWithWebIdentityInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "AssumeRoleWithWebIdentity", params, optFns, c.addOperationAssumeRoleWithWebIdentityMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*AssumeRoleWithWebIdentityOutput) - out.ResultMetadata = metadata - return out, nil -} - -type AssumeRoleWithWebIdentityInput struct { - - // The Amazon Resource Name (ARN) of the role that the caller is assuming. - // - // Additional considerations apply to Amazon Cognito identity pools that assume [cross-account IAM roles]. - // The trust policies of these roles must accept the cognito-identity.amazonaws.com - // service principal and must contain the cognito-identity.amazonaws.com:aud - // condition key to restrict role assumption to users from your intended identity - // pools. A policy that trusts Amazon Cognito identity pools without this condition - // creates a risk that a user from an unintended identity pool can assume the role. - // For more information, see [Trust policies for IAM roles in Basic (Classic) authentication]in the Amazon Cognito Developer Guide. - // - // [cross-account IAM roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies-cross-account-resource-access.html - // [Trust policies for IAM roles in Basic (Classic) authentication]: https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#trust-policies - // - // This member is required. - RoleArn *string - - // An identifier for the assumed role session. Typically, you pass the name or - // identifier that is associated with the user who is using your application. That - // way, the temporary security credentials that your application will use are - // associated with that user. This session name is included as part of the ARN and - // assumed role ID in the AssumedRoleUser response element. - // - // For security purposes, administrators can view this field in [CloudTrail logs] to help identify - // who performed an action in Amazon Web Services. Your administrator might require - // that you specify your user name as the session name when you assume the role. - // For more information, see [sts:RoleSessionName]sts:RoleSessionName . - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- - // - // [CloudTrail logs]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html#cloudtrail-integration_signin-tempcreds - // [sts:RoleSessionName]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#ck_rolesessionname - // - // This member is required. - RoleSessionName *string - - // The OAuth 2.0 access token or OpenID Connect ID token that is provided by the - // identity provider. Your application must get this token by authenticating the - // user who is using your application with a web identity provider before the - // application makes an AssumeRoleWithWebIdentity call. Timestamps in the token - // must be formatted as either an integer or a long integer. Tokens must be signed - // using either RSA keys (RS256, RS384, or RS512) or ECDSA keys (ES256, ES384, or - // ES512). - // - // This member is required. - WebIdentityToken *string - - // The duration, in seconds, of the role session. The value can range from 900 - // seconds (15 minutes) up to the maximum session duration setting for the role. - // This setting can have a value from 1 hour to 12 hours. If you specify a value - // higher than this setting, the operation fails. For example, if you specify a - // session duration of 12 hours, but your administrator set the maximum session - // duration to 6 hours, your operation fails. To learn how to view the maximum - // value for your role, see [View the Maximum Session Duration Setting for a Role]in the IAM User Guide. - // - // By default, the value is set to 3600 seconds. - // - // The DurationSeconds parameter is separate from the duration of a console - // session that you might request using the returned credentials. The request to - // the federation endpoint for a console sign-in token takes a SessionDuration - // parameter that specifies the maximum length of the console session. For more - // information, see [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]in the IAM User Guide. - // - // [View the Maximum Session Duration Setting for a Role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session - // [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html - DurationSeconds *int32 - - // An IAM policy in JSON format that you want to use as an inline session policy. - // - // This parameter is optional. Passing policies to this operation returns new - // temporary credentials. The resulting session's permissions are the intersection - // of the role's identity-based policy and the session policies. You can use the - // role's temporary credentials in subsequent Amazon Web Services API calls to - // access resources in the account that owns the role. You cannot use session - // policies to grant more permissions than those allowed by the identity-based - // policy of the role that is being assumed. For more information, see [Session Policies]in the IAM - // User Guide. - // - // The plaintext that you use for both inline and managed session policies can't - // exceed 2,048 characters. The JSON policy characters can be any ASCII character - // from the space character to the end of the valid character list (\u0020 through - // \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage - // return (\u000D) characters. - // - // For more information about role session permissions, see [Session policies]. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - // [Session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - Policy *string - - // The Amazon Resource Names (ARNs) of the IAM managed policies that you want to - // use as managed session policies. The policies must exist in the same account as - // the role. - // - // This parameter is optional. You can provide up to 10 managed policy ARNs. - // However, the plaintext that you use for both inline and managed session policies - // can't exceed 2,048 characters. For more information about ARNs, see [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]in the - // Amazon Web Services General Reference. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // Passing policies to this operation returns new temporary credentials. The - // resulting session's permissions are the intersection of the role's - // identity-based policy and the session policies. You can use the role's temporary - // credentials in subsequent Amazon Web Services API calls to access resources in - // the account that owns the role. You cannot use session policies to grant more - // permissions than those allowed by the identity-based policy of the role that is - // being assumed. For more information, see [Session Policies]in the IAM User Guide. - // - // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - // [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html - PolicyArns []types.PolicyDescriptorType - - // The fully qualified host component of the domain name of the OAuth 2.0 identity - // provider. Do not specify this value for an OpenID Connect identity provider. - // - // Currently www.amazon.com and graph.facebook.com are the only supported identity - // providers for OAuth 2.0 access tokens. Do not include URL schemes and port - // numbers. - // - // Do not specify this value for OpenID Connect ID tokens. - ProviderId *string - - noSmithyDocumentSerde -} - -// Contains the response to a successful AssumeRoleWithWebIdentity request, including temporary Amazon Web -// Services credentials that can be used to make Amazon Web Services requests. -type AssumeRoleWithWebIdentityOutput struct { - - // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers - // that you can use to refer to the resulting temporary security credentials. For - // example, you can reference these credentials as a principal in a resource-based - // policy by using the ARN or assumed role ID. The ARN and ID include the - // RoleSessionName that you specified when you called AssumeRole . - AssumedRoleUser *types.AssumedRoleUser - - // The intended audience (also known as client ID) of the web identity token. This - // is traditionally the client identifier issued to the application that requested - // the web identity token. - Audience *string - - // The temporary security credentials, which include an access key ID, a secret - // access key, and a security token. - // - // The size of the security token that STS API operations return is not fixed. We - // strongly recommend that you make no assumptions about the maximum size. - Credentials *types.Credentials - - // A percentage value that indicates the packed size of the session policies and - // session tags combined passed in the request. The request fails if the packed - // size is greater than 100 percent, which means the policies and tags exceeded the - // allowed space. - PackedPolicySize *int32 - - // The issuing authority of the web identity token presented. For OpenID Connect - // ID tokens, this contains the value of the iss field. For OAuth 2.0 access - // tokens, this contains the value of the ProviderId parameter that was passed in - // the AssumeRoleWithWebIdentity request. - Provider *string - - // The value of the source identity that is returned in the JSON web token (JWT) - // from the identity provider. - // - // You can require users to set a source identity value when they assume a role. - // You do this by using the sts:SourceIdentity condition key in a role trust - // policy. That way, actions that are taken with the role are associated with that - // user. After the source identity is set, the value cannot be changed. It is - // present in the request for all actions that are taken by the role and persists - // across [chained role]sessions. You can configure your identity provider to use an attribute - // associated with your users, like user name or email, as the source identity when - // calling AssumeRoleWithWebIdentity . You do this by adding a claim to the JSON - // web token. To learn more about OIDC tokens and claims, see [Using Tokens with User Pools]in the Amazon - // Cognito Developer Guide. For more information about using source identity, see [Monitor and control actions taken with assumed roles] - // in the IAM User Guide. - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- - // - // [chained role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#id_roles_terms-and-concepts - // [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html - // [Using Tokens with User Pools]: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html - SourceIdentity *string - - // The unique user identifier that is returned by the identity provider. This - // identifier is associated with the WebIdentityToken that was submitted with the - // AssumeRoleWithWebIdentity call. The identifier is typically unique to the user - // and the application that acquired the WebIdentityToken (pairwise identifier). - // For OpenID Connect ID tokens, this field contains the value returned by the - // identity provider as the token's sub (Subject) claim. - SubjectFromWebIdentityToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpAssumeRoleWithWebIdentity{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpAssumeRoleWithWebIdentity{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "AssumeRoleWithWebIdentity"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = addOpAssumeRoleWithWebIdentityValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opAssumeRoleWithWebIdentity(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opAssumeRoleWithWebIdentity(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "AssumeRoleWithWebIdentity", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go deleted file mode 100644 index 009c405..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go +++ /dev/null @@ -1,232 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a set of short term credentials you can use to perform privileged tasks -// on a member account in your organization. You must use credentials from an -// Organizations management account or a delegated administrator account for IAM to -// call AssumeRoot . You cannot use root user credentials to make this call. -// -// Before you can launch a privileged session, you must have centralized root -// access in your organization. For steps to enable this feature, see [Centralize root access for member accounts]in the IAM -// User Guide. -// -// The STS global endpoint is not supported for AssumeRoot. You must send this -// request to a Regional STS endpoint. For more information, see [Endpoints]. -// -// You can track AssumeRoot in CloudTrail logs to determine what actions were -// performed in a session. For more information, see [Track privileged tasks in CloudTrail]in the IAM User Guide. -// -// When granting access to privileged tasks you should only grant the necessary -// permissions required to perform that task. For more information, see [Security best practices in IAM]. In -// addition, you can use [service control policies](SCPs) to manage and limit permissions in your -// organization. See [General examples]in the Organizations User Guide for more information on SCPs. -// -// [Endpoints]: https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html#sts-endpoints -// [Security best practices in IAM]: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html -// [Track privileged tasks in CloudTrail]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-track-privileged-tasks.html -// [General examples]: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples_general.html -// [service control policies]: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html -// [Centralize root access for member accounts]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-enable-root-access.html -func (c *Client) AssumeRoot(ctx context.Context, params *AssumeRootInput, optFns ...func(*Options)) (*AssumeRootOutput, error) { - if params == nil { - params = &AssumeRootInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "AssumeRoot", params, optFns, c.addOperationAssumeRootMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*AssumeRootOutput) - out.ResultMetadata = metadata - return out, nil -} - -type AssumeRootInput struct { - - // The member account principal ARN or account ID. - // - // This member is required. - TargetPrincipal *string - - // The identity based policy that scopes the session to the privileged tasks that - // can be performed. You must - // - // use one of following Amazon Web Services managed policies to scope root session - // actions: - // - // [IAMAuditRootUserCredentials] - // - // [IAMCreateRootUserPassword] - // - // [IAMDeleteRootUserCredentials] - // - // [S3UnlockBucketPolicy] - // - // [SQSUnlockQueuePolicy] - // - // [IAMDeleteRootUserCredentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-IAMDeleteRootUserCredentials - // [IAMCreateRootUserPassword]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-IAMCreateRootUserPassword - // [IAMAuditRootUserCredentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-IAMAuditRootUserCredentials - // [S3UnlockBucketPolicy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-S3UnlockBucketPolicy - // [SQSUnlockQueuePolicy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/security-iam-awsmanpol.html#security-iam-awsmanpol-SQSUnlockQueuePolicy - // - // This member is required. - TaskPolicyArn *types.PolicyDescriptorType - - // The duration, in seconds, of the privileged session. The value can range from 0 - // seconds up to the maximum session duration of 900 seconds (15 minutes). If you - // specify a value higher than this setting, the operation fails. - // - // By default, the value is set to 900 seconds. - DurationSeconds *int32 - - noSmithyDocumentSerde -} - -type AssumeRootOutput struct { - - // The temporary security credentials, which include an access key ID, a secret - // access key, and a security token. - // - // The size of the security token that STS API operations return is not fixed. We - // strongly recommend that you make no assumptions about the maximum size. - Credentials *types.Credentials - - // The source identity specified by the principal that is calling the AssumeRoot - // operation. - // - // You can use the aws:SourceIdentity condition key to control access based on the - // value of source identity. For more information about using source identity, see [Monitor and control actions taken with assumed roles] - // in the IAM User Guide. - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- - // - // [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html - SourceIdentity *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationAssumeRootMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpAssumeRoot{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpAssumeRoot{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "AssumeRoot"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = addOpAssumeRootValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opAssumeRoot(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opAssumeRoot(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "AssumeRoot", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go deleted file mode 100644 index b00b0c4..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go +++ /dev/null @@ -1,192 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Decodes additional information about the authorization status of a request from -// an encoded message returned in response to an Amazon Web Services request. -// -// For example, if a user is not authorized to perform an operation that he or she -// has requested, the request returns a Client.UnauthorizedOperation response (an -// HTTP 403 response). Some Amazon Web Services operations additionally return an -// encoded message that can provide details about this authorization failure. -// -// Only certain Amazon Web Services operations return an encoded authorization -// message. The documentation for an individual operation indicates whether that -// operation returns an encoded message in addition to returning an HTTP code. -// -// The message is encoded because the details of the authorization status can -// contain privileged information that the user who requested the operation should -// not see. To decode an authorization status message, a user must be granted -// permissions through an IAM [policy]to request the DecodeAuthorizationMessage ( -// sts:DecodeAuthorizationMessage ) action. -// -// The decoded message includes the following type of information: -// -// - Whether the request was denied due to an explicit deny or due to the -// absence of an explicit allow. For more information, see [Determining Whether a Request is Allowed or Denied]in the IAM User -// Guide. -// -// - The principal who made the request. -// -// - The requested action. -// -// - The requested resource. -// -// - The values of condition keys in the context of the user's request. -// -// [Determining Whether a Request is Allowed or Denied]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow -// [policy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html -func (c *Client) DecodeAuthorizationMessage(ctx context.Context, params *DecodeAuthorizationMessageInput, optFns ...func(*Options)) (*DecodeAuthorizationMessageOutput, error) { - if params == nil { - params = &DecodeAuthorizationMessageInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "DecodeAuthorizationMessage", params, optFns, c.addOperationDecodeAuthorizationMessageMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*DecodeAuthorizationMessageOutput) - out.ResultMetadata = metadata - return out, nil -} - -type DecodeAuthorizationMessageInput struct { - - // The encoded message that was returned with the response. - // - // This member is required. - EncodedMessage *string - - noSmithyDocumentSerde -} - -// A document that contains additional information about the authorization status -// of a request from an encoded message that is returned in response to an Amazon -// Web Services request. -type DecodeAuthorizationMessageOutput struct { - - // The API returns a response with the decoded message. - DecodedMessage *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpDecodeAuthorizationMessage{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpDecodeAuthorizationMessage{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "DecodeAuthorizationMessage"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = addOpDecodeAuthorizationMessageValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDecodeAuthorizationMessage(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opDecodeAuthorizationMessage(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "DecodeAuthorizationMessage", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go deleted file mode 100644 index 887bb08..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go +++ /dev/null @@ -1,183 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns the account identifier for the specified access key ID. -// -// Access keys consist of two parts: an access key ID (for example, -// AKIAIOSFODNN7EXAMPLE ) and a secret access key (for example, -// wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY ). For more information about access -// keys, see [Managing Access Keys for IAM Users]in the IAM User Guide. -// -// When you pass an access key ID to this operation, it returns the ID of the -// Amazon Web Services account to which the keys belong. Access key IDs beginning -// with AKIA are long-term credentials for an IAM user or the Amazon Web Services -// account root user. Access key IDs beginning with ASIA are temporary credentials -// that are created using STS operations. If the account in the response belongs to -// you, you can sign in as the root user and review your root user access keys. -// Then, you can pull a [credentials report]to learn which IAM user owns the keys. To learn who -// requested the temporary credentials for an ASIA access key, view the STS events -// in your [CloudTrail logs]in the IAM User Guide. -// -// This operation does not indicate the state of the access key. The key might be -// active, inactive, or deleted. Active keys might not have permissions to perform -// an operation. Providing a deleted access key might return an error that the key -// doesn't exist. -// -// [credentials report]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report.html -// [CloudTrail logs]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html -// [Managing Access Keys for IAM Users]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html -func (c *Client) GetAccessKeyInfo(ctx context.Context, params *GetAccessKeyInfoInput, optFns ...func(*Options)) (*GetAccessKeyInfoOutput, error) { - if params == nil { - params = &GetAccessKeyInfoInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetAccessKeyInfo", params, optFns, c.addOperationGetAccessKeyInfoMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetAccessKeyInfoOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetAccessKeyInfoInput struct { - - // The identifier of an access key. - // - // This parameter allows (through its regex pattern) a string of characters that - // can consist of any upper- or lowercase letter or digit. - // - // This member is required. - AccessKeyId *string - - noSmithyDocumentSerde -} - -type GetAccessKeyInfoOutput struct { - - // The number used to identify the Amazon Web Services account. - Account *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpGetAccessKeyInfo{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetAccessKeyInfo{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetAccessKeyInfo"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = addOpGetAccessKeyInfoValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetAccessKeyInfo(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetAccessKeyInfo(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetAccessKeyInfo", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go deleted file mode 100644 index 2c8d886..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go +++ /dev/null @@ -1,195 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns details about the IAM user or role whose credentials are used to call -// the operation. -// -// No permissions are required to perform this operation. If an administrator -// attaches a policy to your identity that explicitly denies access to the -// sts:GetCallerIdentity action, you can still perform this operation. Permissions -// are not required because the same information is returned when access is denied. -// To view an example response, see [I Am Not Authorized to Perform: iam:DeleteVirtualMFADevice]in the IAM User Guide. -// -// [I Am Not Authorized to Perform: iam:DeleteVirtualMFADevice]: https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_access-denied-delete-mfa -func (c *Client) GetCallerIdentity(ctx context.Context, params *GetCallerIdentityInput, optFns ...func(*Options)) (*GetCallerIdentityOutput, error) { - if params == nil { - params = &GetCallerIdentityInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetCallerIdentity", params, optFns, c.addOperationGetCallerIdentityMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetCallerIdentityOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetCallerIdentityInput struct { - noSmithyDocumentSerde -} - -// Contains the response to a successful GetCallerIdentity request, including information about the -// entity making the request. -type GetCallerIdentityOutput struct { - - // The Amazon Web Services account ID number of the account that owns or contains - // the calling entity. - Account *string - - // The Amazon Web Services ARN associated with the calling entity. - Arn *string - - // The unique identifier of the calling entity. The exact value depends on the - // type of entity that is making the call. The values returned are those listed in - // the aws:userid column in the [Principal table]found on the Policy Variables reference page in - // the IAM User Guide. - // - // [Principal table]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#principaltable - UserId *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpGetCallerIdentity{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetCallerIdentity{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetCallerIdentity"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetCallerIdentity(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetCallerIdentity(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetCallerIdentity", - } -} - -// PresignGetCallerIdentity is used to generate a presigned HTTP Request which -// contains presigned URL, signed headers and HTTP method used. -func (c *PresignClient) PresignGetCallerIdentity(ctx context.Context, params *GetCallerIdentityInput, optFns ...func(*PresignOptions)) (*v4.PresignedHTTPRequest, error) { - if params == nil { - params = &GetCallerIdentityInput{} - } - options := c.options.copy() - for _, fn := range optFns { - fn(&options) - } - clientOptFns := append(options.ClientOptions, withNopHTTPClientAPIOption) - - result, _, err := c.client.invokeOperation(ctx, "GetCallerIdentity", params, clientOptFns, - c.client.addOperationGetCallerIdentityMiddlewares, - presignConverter(options).convertToPresignMiddleware, - ) - if err != nil { - return nil, err - } - - out := result.(*v4.PresignedHTTPRequest) - return out, nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go deleted file mode 100644 index 092ec13..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go +++ /dev/null @@ -1,172 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Exchanges a trade-in token for temporary Amazon Web Services credentials with -// the permissions associated with the assumed principal. This operation allows you -// to obtain credentials for a specific principal based on a trade-in token, -// enabling delegation of access to Amazon Web Services resources. -func (c *Client) GetDelegatedAccessToken(ctx context.Context, params *GetDelegatedAccessTokenInput, optFns ...func(*Options)) (*GetDelegatedAccessTokenOutput, error) { - if params == nil { - params = &GetDelegatedAccessTokenInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetDelegatedAccessToken", params, optFns, c.addOperationGetDelegatedAccessTokenMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetDelegatedAccessTokenOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetDelegatedAccessTokenInput struct { - - // The token to exchange for temporary Amazon Web Services credentials. This token - // must be valid and unexpired at the time of the request. - // - // This member is required. - TradeInToken *string - - noSmithyDocumentSerde -} - -type GetDelegatedAccessTokenOutput struct { - - // The Amazon Resource Name (ARN) of the principal that was assumed when obtaining - // the delegated access token. This ARN identifies the IAM entity whose permissions - // are granted by the temporary credentials. - AssumedPrincipal *string - - // Amazon Web Services credentials for API authentication. - Credentials *types.Credentials - - // The percentage of the maximum policy size that is used by the session policy. - // The policy size is calculated as the sum of all the session policies and - // permission boundaries attached to the session. If the packed size exceeds 100%, - // the request fails. - PackedPolicySize *int32 - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetDelegatedAccessTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpGetDelegatedAccessToken{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetDelegatedAccessToken{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetDelegatedAccessToken"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = addOpGetDelegatedAccessTokenValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetDelegatedAccessToken(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetDelegatedAccessToken(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetDelegatedAccessToken", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go deleted file mode 100644 index e0fc9a5..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go +++ /dev/null @@ -1,396 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a set of temporary security credentials (consisting of an access key -// ID, a secret access key, and a security token) for a user. A typical use is in a -// proxy application that gets temporary security credentials on behalf of -// distributed applications inside a corporate network. -// -// You must call the GetFederationToken operation using the long-term security -// credentials of an IAM user. As a result, this call is appropriate in contexts -// where those credentials can be safeguarded, usually in a server-based -// application. For a comparison of GetFederationToken with the other API -// operations that produce temporary credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the IAM User Guide. -// -// Although it is possible to call GetFederationToken using the security -// credentials of an Amazon Web Services account root user rather than an IAM user -// that you create for the purpose of a proxy application, we do not recommend it. -// For more information, see [Safeguard your root user credentials and don't use them for everyday tasks]in the IAM User Guide. -// -// You can create a mobile-based or browser-based app that can authenticate users -// using a web identity provider like Login with Amazon, Facebook, Google, or an -// OpenID Connect-compatible identity provider. In this case, we recommend that you -// use [Amazon Cognito]or AssumeRoleWithWebIdentity . For more information, see [Federation Through a Web-based Identity Provider] in the IAM User -// Guide. -// -// # Session duration -// -// The temporary credentials are valid for the specified duration, from 900 -// seconds (15 minutes) up to a maximum of 129,600 seconds (36 hours). The default -// session duration is 43,200 seconds (12 hours). Temporary credentials obtained by -// using the root user credentials have a maximum duration of 3,600 seconds (1 -// hour). -// -// # Permissions -// -// You can use the temporary credentials created by GetFederationToken in any -// Amazon Web Services service with the following exceptions: -// -// - You cannot call any IAM operations using the CLI or the Amazon Web Services -// API. This limitation does not apply to console sessions. -// -// - You cannot call any STS operations except GetCallerIdentity . -// -// You can use temporary credentials for single sign-on (SSO) to the console. -// -// You must pass an inline or managed [session policy] to this operation. You can pass a single -// JSON policy document to use as an inline session policy. You can also specify up -// to 10 managed policy Amazon Resource Names (ARNs) to use as managed session -// policies. The plaintext that you use for both inline and managed session -// policies can't exceed 2,048 characters. -// -// Though the session policy parameters are optional, if you do not pass a policy, -// then the resulting federated user session has no permissions. When you pass -// session policies, the session permissions are the intersection of the IAM user -// policies and the session policies that you pass. This gives you a way to further -// restrict the permissions for a federated user. You cannot use session policies -// to grant more permissions than those that are defined in the permissions policy -// of the IAM user. For more information, see [Session Policies]in the IAM User Guide. For -// information about using GetFederationToken to create temporary security -// credentials, see [GetFederationToken—Federation Through a Custom Identity Broker]. -// -// You can use the credentials to access a resource that has a resource-based -// policy. If that policy specifically references the federated user session in the -// Principal element of the policy, the session has the permissions allowed by the -// policy. These permissions are granted in addition to the permissions granted by -// the session policies. -// -// # Tags -// -// (Optional) You can pass tag key-value pairs to your session. These are called -// session tags. For more information about session tags, see [Passing Session Tags in STS]in the IAM User -// Guide. -// -// You can create a mobile-based or browser-based app that can authenticate users -// using a web identity provider like Login with Amazon, Facebook, Google, or an -// OpenID Connect-compatible identity provider. In this case, we recommend that you -// use [Amazon Cognito]or AssumeRoleWithWebIdentity . For more information, see [Federation Through a Web-based Identity Provider] in the IAM User -// Guide. -// -// An administrator must grant you the permissions necessary to pass session tags. -// The administrator can also create granular permissions to allow you to pass only -// specific session tags. For more information, see [Tutorial: Using Tags for Attribute-Based Access Control]in the IAM User Guide. -// -// Tag key–value pairs are not case sensitive, but case is preserved. This means -// that you cannot have separate Department and department tag keys. Assume that -// the user that you are federating has the Department = Marketing tag and you -// pass the department = engineering session tag. Department and department are -// not saved as separate tags, and the session tag passed in the request takes -// precedence over the user tag. -// -// [Federation Through a Web-based Identity Provider]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity -// [session policy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session -// [Amazon Cognito]: http://aws.amazon.com/cognito/ -// [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session -// [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html -// [GetFederationToken—Federation Through a Custom Identity Broker]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken -// [Safeguard your root user credentials and don't use them for everyday tasks]: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#lock-away-credentials -// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html -// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html -// [Tutorial: Using Tags for Attribute-Based Access Control]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html -func (c *Client) GetFederationToken(ctx context.Context, params *GetFederationTokenInput, optFns ...func(*Options)) (*GetFederationTokenOutput, error) { - if params == nil { - params = &GetFederationTokenInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetFederationToken", params, optFns, c.addOperationGetFederationTokenMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetFederationTokenOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetFederationTokenInput struct { - - // The name of the federated user. The name is used as an identifier for the - // temporary security credentials (such as Bob ). For example, you can reference - // the federated user name in a resource-based policy, such as in an Amazon S3 - // bucket policy. - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- - // - // This member is required. - Name *string - - // The duration, in seconds, that the session should last. Acceptable durations - // for federation sessions range from 900 seconds (15 minutes) to 129,600 seconds - // (36 hours), with 43,200 seconds (12 hours) as the default. Sessions obtained - // using root user credentials are restricted to a maximum of 3,600 seconds (one - // hour). If the specified duration is longer than one hour, the session obtained - // by using root user credentials defaults to one hour. - DurationSeconds *int32 - - // An IAM policy in JSON format that you want to use as an inline session policy. - // - // You must pass an inline or managed [session policy] to this operation. You can pass a single - // JSON policy document to use as an inline session policy. You can also specify up - // to 10 managed policy Amazon Resource Names (ARNs) to use as managed session - // policies. - // - // This parameter is optional. However, if you do not pass any session policies, - // then the resulting federated user session has no permissions. - // - // When you pass session policies, the session permissions are the intersection of - // the IAM user policies and the session policies that you pass. This gives you a - // way to further restrict the permissions for a federated user. You cannot use - // session policies to grant more permissions than those that are defined in the - // permissions policy of the IAM user. For more information, see [Session Policies]in the IAM User - // Guide. - // - // The resulting credentials can be used to access a resource that has a - // resource-based policy. If that policy specifically references the federated user - // session in the Principal element of the policy, the session has the permissions - // allowed by the policy. These permissions are granted in addition to the - // permissions that are granted by the session policies. - // - // The plaintext that you use for both inline and managed session policies can't - // exceed 2,048 characters. The JSON policy characters can be any ASCII character - // from the space character to the end of the valid character list (\u0020 through - // \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage - // return (\u000D) characters. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // [session policy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - Policy *string - - // The Amazon Resource Names (ARNs) of the IAM managed policies that you want to - // use as a managed session policy. The policies must exist in the same account as - // the IAM user that is requesting federated access. - // - // You must pass an inline or managed [session policy] to this operation. You can pass a single - // JSON policy document to use as an inline session policy. You can also specify up - // to 10 managed policy Amazon Resource Names (ARNs) to use as managed session - // policies. The plaintext that you use for both inline and managed session - // policies can't exceed 2,048 characters. You can provide up to 10 managed policy - // ARNs. For more information about ARNs, see [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]in the Amazon Web Services General - // Reference. - // - // This parameter is optional. However, if you do not pass any session policies, - // then the resulting federated user session has no permissions. - // - // When you pass session policies, the session permissions are the intersection of - // the IAM user policies and the session policies that you pass. This gives you a - // way to further restrict the permissions for a federated user. You cannot use - // session policies to grant more permissions than those that are defined in the - // permissions policy of the IAM user. For more information, see [Session Policies]in the IAM User - // Guide. - // - // The resulting credentials can be used to access a resource that has a - // resource-based policy. If that policy specifically references the federated user - // session in the Principal element of the policy, the session has the permissions - // allowed by the policy. These permissions are granted in addition to the - // permissions that are granted by the session policies. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // [session policy]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session - // [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html - PolicyArns []types.PolicyDescriptorType - - // A list of session tags. Each session tag consists of a key name and an - // associated value. For more information about session tags, see [Passing Session Tags in STS]in the IAM User - // Guide. - // - // This parameter is optional. You can pass up to 50 session tags. The plaintext - // session tag keys can’t exceed 128 characters and the values can’t exceed 256 - // characters. For these and additional limits, see [IAM and STS Character Limits]in the IAM User Guide. - // - // An Amazon Web Services conversion compresses the passed inline session policy, - // managed policy ARNs, and session tags into a packed binary format that has a - // separate limit. Your request can fail for this limit even if your plaintext - // meets the other requirements. The PackedPolicySize response element indicates - // by percentage how close the policies and tags for your request are to the upper - // size limit. - // - // You can pass a session tag with the same key as a tag that is already attached - // to the user you are federating. When you do, session tags override a user tag - // with the same key. - // - // Tag key–value pairs are not case sensitive, but case is preserved. This means - // that you cannot have separate Department and department tag keys. Assume that - // the role has the Department = Marketing tag and you pass the department = - // engineering session tag. Department and department are not saved as separate - // tags, and the session tag passed in the request takes precedence over the role - // tag. - // - // [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html - // [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length - Tags []types.Tag - - noSmithyDocumentSerde -} - -// Contains the response to a successful GetFederationToken request, including temporary Amazon Web -// Services credentials that can be used to make Amazon Web Services requests. -type GetFederationTokenOutput struct { - - // The temporary security credentials, which include an access key ID, a secret - // access key, and a security (or session) token. - // - // The size of the security token that STS API operations return is not fixed. We - // strongly recommend that you make no assumptions about the maximum size. - Credentials *types.Credentials - - // Identifiers for the federated user associated with the credentials (such as - // arn:aws:sts::123456789012:federated-user/Bob or 123456789012:Bob ). You can use - // the federated user's ARN in your resource-based policies, such as an Amazon S3 - // bucket policy. - FederatedUser *types.FederatedUser - - // A percentage value that indicates the packed size of the session policies and - // session tags combined passed in the request. The request fails if the packed - // size is greater than 100 percent, which means the policies and tags exceeded the - // allowed space. - PackedPolicySize *int32 - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpGetFederationToken{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetFederationToken{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetFederationToken"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = addOpGetFederationTokenValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetFederationToken(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetFederationToken(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetFederationToken", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go deleted file mode 100644 index 2f931f4..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go +++ /dev/null @@ -1,242 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Returns a set of temporary credentials for an Amazon Web Services account or -// IAM user. The credentials consist of an access key ID, a secret access key, and -// a security token. Typically, you use GetSessionToken if you want to use MFA to -// protect programmatic calls to specific Amazon Web Services API operations like -// Amazon EC2 StopInstances . -// -// MFA-enabled IAM users must call GetSessionToken and submit an MFA code that is -// associated with their MFA device. Using the temporary security credentials that -// the call returns, IAM users can then make programmatic calls to API operations -// that require MFA authentication. An incorrect MFA code causes the API to return -// an access denied error. For a comparison of GetSessionToken with the other API -// operations that produce temporary credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the IAM User Guide. -// -// No permissions are required for users to perform this operation. The purpose of -// the sts:GetSessionToken operation is to authenticate the user using MFA. You -// cannot use policies to control authentication operations. For more information, -// see [Permissions for GetSessionToken]in the IAM User Guide. -// -// # Session Duration -// -// The GetSessionToken operation must be called by using the long-term Amazon Web -// Services security credentials of an IAM user. Credentials that are created by -// IAM users are valid for the duration that you specify. This duration can range -// from 900 seconds (15 minutes) up to a maximum of 129,600 seconds (36 hours), -// with a default of 43,200 seconds (12 hours). Credentials based on account -// credentials can range from 900 seconds (15 minutes) up to 3,600 seconds (1 -// hour), with a default of 1 hour. -// -// # Permissions -// -// The temporary security credentials created by GetSessionToken can be used to -// make API calls to any Amazon Web Services service with the following exceptions: -// -// - You cannot call any IAM API operations unless MFA authentication -// information is included in the request. -// -// - You cannot call any STS API except AssumeRole or GetCallerIdentity . -// -// The credentials that GetSessionToken returns are based on permissions -// associated with the IAM user whose credentials were used to call the operation. -// The temporary credentials have the same permissions as the IAM user. -// -// Although it is possible to call GetSessionToken using the security credentials -// of an Amazon Web Services account root user rather than an IAM user, we do not -// recommend it. If GetSessionToken is called using root user credentials, the -// temporary credentials have root user permissions. For more information, see [Safeguard your root user credentials and don't use them for everyday tasks]in -// the IAM User Guide -// -// For more information about using GetSessionToken to create temporary -// credentials, see [Temporary Credentials for Users in Untrusted Environments]in the IAM User Guide. -// -// [Permissions for GetSessionToken]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getsessiontoken.html -// [Temporary Credentials for Users in Untrusted Environments]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken -// [Safeguard your root user credentials and don't use them for everyday tasks]: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#lock-away-credentials -// [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html -// [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html -func (c *Client) GetSessionToken(ctx context.Context, params *GetSessionTokenInput, optFns ...func(*Options)) (*GetSessionTokenOutput, error) { - if params == nil { - params = &GetSessionTokenInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetSessionToken", params, optFns, c.addOperationGetSessionTokenMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetSessionTokenOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetSessionTokenInput struct { - - // The duration, in seconds, that the credentials should remain valid. Acceptable - // durations for IAM user sessions range from 900 seconds (15 minutes) to 129,600 - // seconds (36 hours), with 43,200 seconds (12 hours) as the default. Sessions for - // Amazon Web Services account owners are restricted to a maximum of 3,600 seconds - // (one hour). If the duration is longer than one hour, the session for Amazon Web - // Services account owners defaults to one hour. - DurationSeconds *int32 - - // The identification number of the MFA device that is associated with the IAM - // user who is making the GetSessionToken call. Specify this value if the IAM user - // has a policy that requires MFA authentication. The value is either the serial - // number for a hardware device (such as GAHT12345678 ) or an Amazon Resource Name - // (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user ). You - // can find the device for an IAM user by going to the Amazon Web Services - // Management Console and viewing the user's security credentials. - // - // The regex used to validate this parameter is a string of characters consisting - // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@:/- - SerialNumber *string - - // The value provided by the MFA device, if MFA is required. If any policy - // requires the IAM user to submit an MFA code, specify this value. If MFA - // authentication is required, the user must provide a code when requesting a set - // of temporary security credentials. A user who fails to provide the code receives - // an "access denied" response when requesting resources that require MFA - // authentication. - // - // The format for this parameter, as described by its regex pattern, is a sequence - // of six numeric digits. - TokenCode *string - - noSmithyDocumentSerde -} - -// Contains the response to a successful GetSessionToken request, including temporary Amazon Web -// Services credentials that can be used to make Amazon Web Services requests. -type GetSessionTokenOutput struct { - - // The temporary security credentials, which include an access key ID, a secret - // access key, and a security (or session) token. - // - // The size of the security token that STS API operations return is not fixed. We - // strongly recommend that you make no assumptions about the maximum size. - Credentials *types.Credentials - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpGetSessionToken{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetSessionToken{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetSessionToken"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetSessionToken(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetSessionToken(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetSessionToken", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go deleted file mode 100644 index 306ee43..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go +++ /dev/null @@ -1,195 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "time" -) - -// Returns a signed JSON Web Token (JWT) that represents the calling Amazon Web -// Services identity. The returned JWT can be used to authenticate with external -// services that support OIDC discovery. The token is signed by Amazon Web Services -// STS and can be publicly verified using the verification keys published at the -// issuer's JWKS endpoint. -func (c *Client) GetWebIdentityToken(ctx context.Context, params *GetWebIdentityTokenInput, optFns ...func(*Options)) (*GetWebIdentityTokenOutput, error) { - if params == nil { - params = &GetWebIdentityTokenInput{} - } - - result, metadata, err := c.invokeOperation(ctx, "GetWebIdentityToken", params, optFns, c.addOperationGetWebIdentityTokenMiddlewares) - if err != nil { - return nil, err - } - - out := result.(*GetWebIdentityTokenOutput) - out.ResultMetadata = metadata - return out, nil -} - -type GetWebIdentityTokenInput struct { - - // The intended recipient of the web identity token. This value populates the aud - // claim in the JWT and should identify the service or application that will - // validate and use the token. The external service should verify this claim to - // ensure the token was intended for their use. - // - // This member is required. - Audience []string - - // The cryptographic algorithm to use for signing the JSON Web Token (JWT). Valid - // values are RS256 (RSA with SHA-256) and ES384 (ECDSA using P-384 curve with - // SHA-384). - // - // This member is required. - SigningAlgorithm *string - - // The duration, in seconds, for which the JSON Web Token (JWT) will remain valid. - // The value can range from 60 seconds (1 minute) to 3600 seconds (1 hour). If not - // specified, the default duration is 300 seconds (5 minutes). The token is - // designed to be short-lived and should be used for proof of identity, then - // exchanged for credentials or short-lived tokens in the external service. - DurationSeconds *int32 - - // An optional list of tags to include in the JSON Web Token (JWT). These tags are - // added as custom claims to the JWT and can be used by the downstream service for - // authorization decisions. - Tags []types.Tag - - noSmithyDocumentSerde -} - -type GetWebIdentityTokenOutput struct { - - // The date and time when the web identity token expires, in UTC. The expiration - // is determined by adding the DurationSeconds value to the time the token was - // issued. After this time, the token should no longer be considered valid. - Expiration *time.Time - - // A signed JSON Web Token (JWT) that represents the caller's Amazon Web Services - // identity. The token contains standard JWT claims such as subject, audience, - // expiration time, and additional identity attributes added by STS as custom - // claims. You can also add your own custom claims to the token by passing tags as - // request parameters to the GetWebIdentityToken API. The token is signed using - // the specified signing algorithm and can be verified using the verification keys - // available at the issuer's JWKS endpoint. - WebIdentityToken *string - - // Metadata pertaining to the operation's result. - ResultMetadata middleware.Metadata - - noSmithyDocumentSerde -} - -func (c *Client) addOperationGetWebIdentityTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { - if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { - return err - } - err = stack.Serialize.Add(&awsAwsquery_serializeOpGetWebIdentityToken{}, middleware.After) - if err != nil { - return err - } - err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetWebIdentityToken{}, middleware.After) - if err != nil { - return err - } - if err := addProtocolFinalizerMiddlewares(stack, options, "GetWebIdentityToken"); err != nil { - return fmt.Errorf("add protocol finalizers: %v", err) - } - - if err = addlegacyEndpointContextSetter(stack, options); err != nil { - return err - } - if err = addSetLoggerMiddleware(stack, options); err != nil { - return err - } - if err = addClientRequestID(stack); err != nil { - return err - } - if err = addComputeContentLength(stack); err != nil { - return err - } - if err = addResolveEndpointMiddleware(stack, options); err != nil { - return err - } - if err = addComputePayloadSHA256(stack); err != nil { - return err - } - if err = addRetry(stack, options); err != nil { - return err - } - if err = addRawResponseToMetadata(stack); err != nil { - return err - } - if err = addRecordResponseTiming(stack); err != nil { - return err - } - if err = addSpanRetryLoop(stack, options); err != nil { - return err - } - if err = addClientUserAgent(stack, options); err != nil { - return err - } - if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { - return err - } - if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { - return err - } - if err = addTimeOffsetBuild(stack, c); err != nil { - return err - } - if err = addUserAgentRetryMode(stack, options); err != nil { - return err - } - if err = addCredentialSource(stack, options); err != nil { - return err - } - if err = addOpGetWebIdentityTokenValidationMiddleware(stack); err != nil { - return err - } - if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetWebIdentityToken(options.Region), middleware.Before); err != nil { - return err - } - if err = addRecursionDetection(stack); err != nil { - return err - } - if err = addRequestIDRetrieverMiddleware(stack); err != nil { - return err - } - if err = addResponseErrorMiddleware(stack); err != nil { - return err - } - if err = addRequestResponseLogging(stack, options); err != nil { - return err - } - if err = addDisableHTTPSMiddleware(stack, options); err != nil { - return err - } - if err = addInterceptBeforeRetryLoop(stack, options); err != nil { - return err - } - if err = addInterceptAttempt(stack, options); err != nil { - return err - } - if err = addInterceptors(stack, options); err != nil { - return err - } - return nil -} - -func newServiceMetadataMiddleware_opGetWebIdentityToken(region string) *awsmiddleware.RegisterServiceMetadata { - return &awsmiddleware.RegisterServiceMetadata{ - Region: region, - ServiceID: ServiceID, - OperationName: "GetWebIdentityToken", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go deleted file mode 100644 index 4db5a51..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go +++ /dev/null @@ -1,357 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - smithy "github.com/aws/smithy-go" - smithyauth "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "slices" - "strings" -) - -func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error { - params.Region = options.Region - return nil -} - -type setLegacyContextSigningOptionsMiddleware struct { -} - -func (*setLegacyContextSigningOptionsMiddleware) ID() string { - return "setLegacyContextSigningOptions" -} - -func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - rscheme := getResolvedAuthScheme(ctx) - schemeID := rscheme.Scheme.SchemeID() - - if sn := awsmiddleware.GetSigningName(ctx); sn != "" { - if schemeID == "aws.auth#sigv4" { - smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn) - } else if schemeID == "aws.auth#sigv4a" { - smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn) - } - } - - if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" { - if schemeID == "aws.auth#sigv4" { - smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr) - } else if schemeID == "aws.auth#sigv4a" { - smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr}) - } - } - - return next.HandleFinalize(ctx, in) -} - -func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error { - return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before) -} - -type withAnonymous struct { - resolver AuthSchemeResolver -} - -var _ AuthSchemeResolver = (*withAnonymous)(nil) - -func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { - opts, err := v.resolver.ResolveAuthSchemes(ctx, params) - if err != nil { - return nil, err - } - - opts = append(opts, &smithyauth.Option{ - SchemeID: smithyauth.SchemeIDAnonymous, - }) - return opts, nil -} - -func wrapWithAnonymousAuth(options *Options) { - if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok { - return - } - - options.AuthSchemeResolver = &withAnonymous{ - resolver: options.AuthSchemeResolver, - } -} - -// AuthResolverParameters contains the set of inputs necessary for auth scheme -// resolution. -type AuthResolverParameters struct { - // The name of the operation being invoked. - Operation string - - // The region in which the operation is being invoked. - Region string -} - -func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) { - params := &AuthResolverParameters{ - Operation: operation, - } - - if err := bindAuthParamsRegion(ctx, params, input, options); err != nil { - return nil, err - } - - return params, nil -} - -// AuthSchemeResolver returns a set of possible authentication options for an -// operation. -type AuthSchemeResolver interface { - ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error) -} - -type defaultAuthSchemeResolver struct{} - -var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil) - -func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { - if overrides, ok := operationAuthOptions[params.Operation]; ok { - return overrides(params), nil - } - return serviceAuthOptions(params), nil -} - -var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{ - "AssumeRoleWithSAML": func(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - {SchemeID: smithyauth.SchemeIDAnonymous}, - } - }, - - "AssumeRoleWithWebIdentity": func(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - {SchemeID: smithyauth.SchemeIDAnonymous}, - } - }, -} - -func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option { - return []*smithyauth.Option{ - { - SchemeID: smithyauth.SchemeIDSigV4, - SignerProperties: func() smithy.Properties { - var props smithy.Properties - smithyhttp.SetSigV4SigningName(&props, "sts") - smithyhttp.SetSigV4SigningRegion(&props, params.Region) - return props - }(), - }, - } -} - -type resolveAuthSchemeMiddleware struct { - operation string - options Options -} - -func (*resolveAuthSchemeMiddleware) ID() string { - return "ResolveAuthScheme" -} - -func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "ResolveAuthScheme") - defer span.End() - - params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) - if err != nil { - return out, metadata, fmt.Errorf("bind auth scheme params: %w", err) - } - options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) - if err != nil { - return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) - } - - scheme, ok := m.selectScheme(options) - if !ok { - return out, metadata, fmt.Errorf("could not select an auth scheme") - } - - ctx = setResolvedAuthScheme(ctx, scheme) - - span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID()) - span.End() - return next.HandleFinalize(ctx, in) -} - -func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - sorted := sortAuthOptions(options, m.options.AuthSchemePreference) - for _, option := range sorted { - if option.SchemeID == smithyauth.SchemeIDAnonymous { - return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true - } - - for _, scheme := range m.options.AuthSchemes { - if scheme.SchemeID() != option.SchemeID { - continue - } - - if scheme.IdentityResolver(m.options) != nil { - return newResolvedAuthScheme(scheme, option), true - } - } - } - - return nil, false -} - -func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option { - byPriority := make([]*smithyauth.Option, 0, len(options)) - for _, prefName := range preferred { - for _, option := range options { - optName := option.SchemeID - if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 { - optName = parts[1] - } - if prefName == optName { - byPriority = append(byPriority, option) - } - } - } - for _, option := range options { - if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool { - return o.SchemeID == option.SchemeID - }) { - byPriority = append(byPriority, option) - } - } - return byPriority -} - -type resolvedAuthSchemeKey struct{} - -type resolvedAuthScheme struct { - Scheme smithyhttp.AuthScheme - IdentityProperties smithy.Properties - SignerProperties smithy.Properties -} - -func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme { - return &resolvedAuthScheme{ - Scheme: scheme, - IdentityProperties: option.IdentityProperties, - SignerProperties: option.SignerProperties, - } -} - -func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context { - return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme) -} - -func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme { - v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme) - return v -} - -type getIdentityMiddleware struct { - options Options -} - -func (*getIdentityMiddleware) ID() string { - return "GetIdentity" -} - -func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - innerCtx, span := tracing.StartSpan(ctx, "GetIdentity") - defer span.End() - - rscheme := getResolvedAuthScheme(innerCtx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - resolver := rscheme.Scheme.IdentityResolver(m.options) - if resolver == nil { - return out, metadata, fmt.Errorf("no identity resolver") - } - - identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration", - func() (smithyauth.Identity, error) { - return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties) - }, - func(o *metrics.RecordMetricOptions) { - o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) - }) - if err != nil { - return out, metadata, fmt.Errorf("get identity: %w", err) - } - - ctx = setIdentity(ctx, identity) - - span.End() - return next.HandleFinalize(ctx, in) -} - -type identityKey struct{} - -func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context { - return middleware.WithStackValue(ctx, identityKey{}, identity) -} - -func getIdentity(ctx context.Context) smithyauth.Identity { - v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity) - return v -} - -type signRequestMiddleware struct { - options Options -} - -func (*signRequestMiddleware) ID() string { - return "Signing" -} - -func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "SignRequest") - defer span.End() - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request) - } - - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - identity := getIdentity(ctx) - if identity == nil { - return out, metadata, fmt.Errorf("no identity") - } - - signer := rscheme.Scheme.Signer() - if signer == nil { - return out, metadata, fmt.Errorf("no signer") - } - - _, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) { - return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties) - }, func(o *metrics.RecordMetricOptions) { - o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) - }) - if err != nil { - return out, metadata, fmt.Errorf("sign request: %w", err) - } - - span.End() - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go deleted file mode 100644 index 8c1ce35..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go +++ /dev/null @@ -1,3456 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "bytes" - "context" - "encoding/xml" - "fmt" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - awsxml "github.com/aws/aws-sdk-go-v2/aws/protocol/xml" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - smithy "github.com/aws/smithy-go" - smithyxml "github.com/aws/smithy-go/encoding/xml" - smithyio "github.com/aws/smithy-go/io" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/ptr" - smithytime "github.com/aws/smithy-go/time" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "io" - "strconv" - "strings" -) - -type awsAwsquery_deserializeOpAssumeRole struct { -} - -func (*awsAwsquery_deserializeOpAssumeRole) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpAssumeRole) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorAssumeRole(response, &metadata) - } - output := &AssumeRoleOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("AssumeRoleResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentAssumeRoleOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorAssumeRole(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - case strings.EqualFold("ExpiredTokenException", errorCode): - return awsAwsquery_deserializeErrorExpiredTokenException(response, errorBody) - - case strings.EqualFold("MalformedPolicyDocument", errorCode): - return awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response, errorBody) - - case strings.EqualFold("PackedPolicyTooLarge", errorCode): - return awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response, errorBody) - - case strings.EqualFold("RegionDisabledException", errorCode): - return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpAssumeRoleWithSAML struct { -} - -func (*awsAwsquery_deserializeOpAssumeRoleWithSAML) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpAssumeRoleWithSAML) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorAssumeRoleWithSAML(response, &metadata) - } - output := &AssumeRoleWithSAMLOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("AssumeRoleWithSAMLResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentAssumeRoleWithSAMLOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorAssumeRoleWithSAML(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - case strings.EqualFold("ExpiredTokenException", errorCode): - return awsAwsquery_deserializeErrorExpiredTokenException(response, errorBody) - - case strings.EqualFold("IDPRejectedClaim", errorCode): - return awsAwsquery_deserializeErrorIDPRejectedClaimException(response, errorBody) - - case strings.EqualFold("InvalidIdentityToken", errorCode): - return awsAwsquery_deserializeErrorInvalidIdentityTokenException(response, errorBody) - - case strings.EqualFold("MalformedPolicyDocument", errorCode): - return awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response, errorBody) - - case strings.EqualFold("PackedPolicyTooLarge", errorCode): - return awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response, errorBody) - - case strings.EqualFold("RegionDisabledException", errorCode): - return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpAssumeRoleWithWebIdentity struct { -} - -func (*awsAwsquery_deserializeOpAssumeRoleWithWebIdentity) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpAssumeRoleWithWebIdentity) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorAssumeRoleWithWebIdentity(response, &metadata) - } - output := &AssumeRoleWithWebIdentityOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("AssumeRoleWithWebIdentityResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentAssumeRoleWithWebIdentityOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorAssumeRoleWithWebIdentity(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - case strings.EqualFold("ExpiredTokenException", errorCode): - return awsAwsquery_deserializeErrorExpiredTokenException(response, errorBody) - - case strings.EqualFold("IDPCommunicationError", errorCode): - return awsAwsquery_deserializeErrorIDPCommunicationErrorException(response, errorBody) - - case strings.EqualFold("IDPRejectedClaim", errorCode): - return awsAwsquery_deserializeErrorIDPRejectedClaimException(response, errorBody) - - case strings.EqualFold("InvalidIdentityToken", errorCode): - return awsAwsquery_deserializeErrorInvalidIdentityTokenException(response, errorBody) - - case strings.EqualFold("MalformedPolicyDocument", errorCode): - return awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response, errorBody) - - case strings.EqualFold("PackedPolicyTooLarge", errorCode): - return awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response, errorBody) - - case strings.EqualFold("RegionDisabledException", errorCode): - return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpAssumeRoot struct { -} - -func (*awsAwsquery_deserializeOpAssumeRoot) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpAssumeRoot) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorAssumeRoot(response, &metadata) - } - output := &AssumeRootOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("AssumeRootResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentAssumeRootOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorAssumeRoot(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - case strings.EqualFold("ExpiredTokenException", errorCode): - return awsAwsquery_deserializeErrorExpiredTokenException(response, errorBody) - - case strings.EqualFold("RegionDisabledException", errorCode): - return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpDecodeAuthorizationMessage struct { -} - -func (*awsAwsquery_deserializeOpDecodeAuthorizationMessage) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpDecodeAuthorizationMessage) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorDecodeAuthorizationMessage(response, &metadata) - } - output := &DecodeAuthorizationMessageOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("DecodeAuthorizationMessageResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentDecodeAuthorizationMessageOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorDecodeAuthorizationMessage(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - case strings.EqualFold("InvalidAuthorizationMessageException", errorCode): - return awsAwsquery_deserializeErrorInvalidAuthorizationMessageException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpGetAccessKeyInfo struct { -} - -func (*awsAwsquery_deserializeOpGetAccessKeyInfo) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpGetAccessKeyInfo) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorGetAccessKeyInfo(response, &metadata) - } - output := &GetAccessKeyInfoOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("GetAccessKeyInfoResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentGetAccessKeyInfoOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorGetAccessKeyInfo(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpGetCallerIdentity struct { -} - -func (*awsAwsquery_deserializeOpGetCallerIdentity) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpGetCallerIdentity) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorGetCallerIdentity(response, &metadata) - } - output := &GetCallerIdentityOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("GetCallerIdentityResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentGetCallerIdentityOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorGetCallerIdentity(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpGetDelegatedAccessToken struct { -} - -func (*awsAwsquery_deserializeOpGetDelegatedAccessToken) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpGetDelegatedAccessToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorGetDelegatedAccessToken(response, &metadata) - } - output := &GetDelegatedAccessTokenOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("GetDelegatedAccessTokenResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentGetDelegatedAccessTokenOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorGetDelegatedAccessToken(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - case strings.EqualFold("ExpiredTradeInTokenException", errorCode): - return awsAwsquery_deserializeErrorExpiredTradeInTokenException(response, errorBody) - - case strings.EqualFold("PackedPolicyTooLarge", errorCode): - return awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response, errorBody) - - case strings.EqualFold("RegionDisabledException", errorCode): - return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpGetFederationToken struct { -} - -func (*awsAwsquery_deserializeOpGetFederationToken) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpGetFederationToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorGetFederationToken(response, &metadata) - } - output := &GetFederationTokenOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("GetFederationTokenResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentGetFederationTokenOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorGetFederationToken(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - case strings.EqualFold("MalformedPolicyDocument", errorCode): - return awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response, errorBody) - - case strings.EqualFold("PackedPolicyTooLarge", errorCode): - return awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response, errorBody) - - case strings.EqualFold("RegionDisabledException", errorCode): - return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpGetSessionToken struct { -} - -func (*awsAwsquery_deserializeOpGetSessionToken) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpGetSessionToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorGetSessionToken(response, &metadata) - } - output := &GetSessionTokenOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("GetSessionTokenResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentGetSessionTokenOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorGetSessionToken(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - case strings.EqualFold("RegionDisabledException", errorCode): - return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -type awsAwsquery_deserializeOpGetWebIdentityToken struct { -} - -func (*awsAwsquery_deserializeOpGetWebIdentityToken) ID() string { - return "OperationDeserializer" -} - -func (m *awsAwsquery_deserializeOpGetWebIdentityToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - _, span := tracing.StartSpan(ctx, "OperationDeserializer") - endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") - defer endTimer() - defer span.End() - response, ok := out.RawResponse.(*smithyhttp.Response) - if !ok { - return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} - } - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsquery_deserializeOpErrorGetWebIdentityToken(response, &metadata) - } - output := &GetWebIdentityTokenOutput{} - out.Result = output - - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(response.Body, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return out, metadata, nil - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return out, metadata, &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("GetWebIdentityTokenResult") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeOpDocumentGetWebIdentityTokenOutput(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - return out, metadata, err - } - - return out, metadata, err -} - -func awsAwsquery_deserializeOpErrorGetWebIdentityToken(response *smithyhttp.Response, metadata *middleware.Metadata) error { - var errorBuffer bytes.Buffer - if _, err := io.Copy(&errorBuffer, response.Body); err != nil { - return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} - } - errorBody := bytes.NewReader(errorBuffer.Bytes()) - - errorCode := "UnknownError" - errorMessage := errorCode - - errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) - if err != nil { - return err - } - if reqID := errorComponents.RequestID; len(reqID) != 0 { - awsmiddleware.SetRequestIDMetadata(metadata, reqID) - } - if len(errorComponents.Code) != 0 { - errorCode = errorComponents.Code - } - if len(errorComponents.Message) != 0 { - errorMessage = errorComponents.Message - } - errorBody.Seek(0, io.SeekStart) - switch { - case strings.EqualFold("JWTPayloadSizeExceededException", errorCode): - return awsAwsquery_deserializeErrorJWTPayloadSizeExceededException(response, errorBody) - - case strings.EqualFold("OutboundWebIdentityFederationDisabledException", errorCode): - return awsAwsquery_deserializeErrorOutboundWebIdentityFederationDisabledException(response, errorBody) - - case strings.EqualFold("SessionDurationEscalationException", errorCode): - return awsAwsquery_deserializeErrorSessionDurationEscalationException(response, errorBody) - - default: - genericError := &smithy.GenericAPIError{ - Code: errorCode, - Message: errorMessage, - } - return genericError - - } -} - -func awsAwsquery_deserializeErrorExpiredTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.ExpiredTokenException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentExpiredTokenException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorExpiredTradeInTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.ExpiredTradeInTokenException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentExpiredTradeInTokenException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorIDPCommunicationErrorException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.IDPCommunicationErrorException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentIDPCommunicationErrorException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorIDPRejectedClaimException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.IDPRejectedClaimException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentIDPRejectedClaimException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorInvalidAuthorizationMessageException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidAuthorizationMessageException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentInvalidAuthorizationMessageException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorInvalidIdentityTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidIdentityTokenException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentInvalidIdentityTokenException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorJWTPayloadSizeExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.JWTPayloadSizeExceededException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentJWTPayloadSizeExceededException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.MalformedPolicyDocumentException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorOutboundWebIdentityFederationDisabledException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.OutboundWebIdentityFederationDisabledException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentOutboundWebIdentityFederationDisabledException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.PackedPolicyTooLargeException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentPackedPolicyTooLargeException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorRegionDisabledException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.RegionDisabledException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentRegionDisabledException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeErrorSessionDurationEscalationException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.SessionDurationEscalationException{} - var buff [1024]byte - ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) - rootDecoder := xml.NewDecoder(body) - t, err := smithyxml.FetchRootElement(rootDecoder) - if err == io.EOF { - return output - } - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) - t, err = decoder.GetElement("Error") - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentSessionDurationEscalationException(&output, decoder) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - return &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), - } - } - - return output -} - -func awsAwsquery_deserializeDocumentAssumedRoleUser(v **types.AssumedRoleUser, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.AssumedRoleUser - if *v == nil { - sv = &types.AssumedRoleUser{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("Arn", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Arn = ptr.String(xtv) - } - - case strings.EqualFold("AssumedRoleId", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.AssumedRoleId = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentCredentials(v **types.Credentials, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.Credentials - if *v == nil { - sv = &types.Credentials{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("AccessKeyId", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.AccessKeyId = ptr.String(xtv) - } - - case strings.EqualFold("Expiration", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - t, err := smithytime.ParseDateTime(xtv) - if err != nil { - return err - } - sv.Expiration = ptr.Time(t) - } - - case strings.EqualFold("SecretAccessKey", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.SecretAccessKey = ptr.String(xtv) - } - - case strings.EqualFold("SessionToken", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.SessionToken = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentExpiredTokenException(v **types.ExpiredTokenException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.ExpiredTokenException - if *v == nil { - sv = &types.ExpiredTokenException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentExpiredTradeInTokenException(v **types.ExpiredTradeInTokenException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.ExpiredTradeInTokenException - if *v == nil { - sv = &types.ExpiredTradeInTokenException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentFederatedUser(v **types.FederatedUser, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.FederatedUser - if *v == nil { - sv = &types.FederatedUser{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("Arn", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Arn = ptr.String(xtv) - } - - case strings.EqualFold("FederatedUserId", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.FederatedUserId = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentIDPCommunicationErrorException(v **types.IDPCommunicationErrorException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.IDPCommunicationErrorException - if *v == nil { - sv = &types.IDPCommunicationErrorException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentIDPRejectedClaimException(v **types.IDPRejectedClaimException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.IDPRejectedClaimException - if *v == nil { - sv = &types.IDPRejectedClaimException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentInvalidAuthorizationMessageException(v **types.InvalidAuthorizationMessageException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.InvalidAuthorizationMessageException - if *v == nil { - sv = &types.InvalidAuthorizationMessageException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentInvalidIdentityTokenException(v **types.InvalidIdentityTokenException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.InvalidIdentityTokenException - if *v == nil { - sv = &types.InvalidIdentityTokenException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentJWTPayloadSizeExceededException(v **types.JWTPayloadSizeExceededException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.JWTPayloadSizeExceededException - if *v == nil { - sv = &types.JWTPayloadSizeExceededException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(v **types.MalformedPolicyDocumentException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.MalformedPolicyDocumentException - if *v == nil { - sv = &types.MalformedPolicyDocumentException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentOutboundWebIdentityFederationDisabledException(v **types.OutboundWebIdentityFederationDisabledException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.OutboundWebIdentityFederationDisabledException - if *v == nil { - sv = &types.OutboundWebIdentityFederationDisabledException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentPackedPolicyTooLargeException(v **types.PackedPolicyTooLargeException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.PackedPolicyTooLargeException - if *v == nil { - sv = &types.PackedPolicyTooLargeException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentRegionDisabledException(v **types.RegionDisabledException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.RegionDisabledException - if *v == nil { - sv = &types.RegionDisabledException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeDocumentSessionDurationEscalationException(v **types.SessionDurationEscalationException, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *types.SessionDurationEscalationException - if *v == nil { - sv = &types.SessionDurationEscalationException{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("message", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Message = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentAssumeRoleOutput(v **AssumeRoleOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *AssumeRoleOutput - if *v == nil { - sv = &AssumeRoleOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("AssumedRoleUser", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentAssumedRoleUser(&sv.AssumedRoleUser, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("Credentials", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("PackedPolicySize", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - i64, err := strconv.ParseInt(xtv, 10, 64) - if err != nil { - return err - } - sv.PackedPolicySize = ptr.Int32(int32(i64)) - } - - case strings.EqualFold("SourceIdentity", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.SourceIdentity = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentAssumeRoleWithSAMLOutput(v **AssumeRoleWithSAMLOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *AssumeRoleWithSAMLOutput - if *v == nil { - sv = &AssumeRoleWithSAMLOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("AssumedRoleUser", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentAssumedRoleUser(&sv.AssumedRoleUser, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("Audience", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Audience = ptr.String(xtv) - } - - case strings.EqualFold("Credentials", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("Issuer", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Issuer = ptr.String(xtv) - } - - case strings.EqualFold("NameQualifier", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.NameQualifier = ptr.String(xtv) - } - - case strings.EqualFold("PackedPolicySize", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - i64, err := strconv.ParseInt(xtv, 10, 64) - if err != nil { - return err - } - sv.PackedPolicySize = ptr.Int32(int32(i64)) - } - - case strings.EqualFold("SourceIdentity", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.SourceIdentity = ptr.String(xtv) - } - - case strings.EqualFold("Subject", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Subject = ptr.String(xtv) - } - - case strings.EqualFold("SubjectType", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.SubjectType = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentAssumeRoleWithWebIdentityOutput(v **AssumeRoleWithWebIdentityOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *AssumeRoleWithWebIdentityOutput - if *v == nil { - sv = &AssumeRoleWithWebIdentityOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("AssumedRoleUser", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentAssumedRoleUser(&sv.AssumedRoleUser, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("Audience", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Audience = ptr.String(xtv) - } - - case strings.EqualFold("Credentials", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("PackedPolicySize", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - i64, err := strconv.ParseInt(xtv, 10, 64) - if err != nil { - return err - } - sv.PackedPolicySize = ptr.Int32(int32(i64)) - } - - case strings.EqualFold("Provider", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Provider = ptr.String(xtv) - } - - case strings.EqualFold("SourceIdentity", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.SourceIdentity = ptr.String(xtv) - } - - case strings.EqualFold("SubjectFromWebIdentityToken", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.SubjectFromWebIdentityToken = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentAssumeRootOutput(v **AssumeRootOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *AssumeRootOutput - if *v == nil { - sv = &AssumeRootOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("Credentials", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("SourceIdentity", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.SourceIdentity = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentDecodeAuthorizationMessageOutput(v **DecodeAuthorizationMessageOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *DecodeAuthorizationMessageOutput - if *v == nil { - sv = &DecodeAuthorizationMessageOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("DecodedMessage", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.DecodedMessage = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentGetAccessKeyInfoOutput(v **GetAccessKeyInfoOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *GetAccessKeyInfoOutput - if *v == nil { - sv = &GetAccessKeyInfoOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("Account", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Account = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentGetCallerIdentityOutput(v **GetCallerIdentityOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *GetCallerIdentityOutput - if *v == nil { - sv = &GetCallerIdentityOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("Account", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Account = ptr.String(xtv) - } - - case strings.EqualFold("Arn", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.Arn = ptr.String(xtv) - } - - case strings.EqualFold("UserId", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.UserId = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentGetDelegatedAccessTokenOutput(v **GetDelegatedAccessTokenOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *GetDelegatedAccessTokenOutput - if *v == nil { - sv = &GetDelegatedAccessTokenOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("AssumedPrincipal", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.AssumedPrincipal = ptr.String(xtv) - } - - case strings.EqualFold("Credentials", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("PackedPolicySize", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - i64, err := strconv.ParseInt(xtv, 10, 64) - if err != nil { - return err - } - sv.PackedPolicySize = ptr.Int32(int32(i64)) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentGetFederationTokenOutput(v **GetFederationTokenOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *GetFederationTokenOutput - if *v == nil { - sv = &GetFederationTokenOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("Credentials", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("FederatedUser", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentFederatedUser(&sv.FederatedUser, nodeDecoder); err != nil { - return err - } - - case strings.EqualFold("PackedPolicySize", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - i64, err := strconv.ParseInt(xtv, 10, 64) - if err != nil { - return err - } - sv.PackedPolicySize = ptr.Int32(int32(i64)) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentGetSessionTokenOutput(v **GetSessionTokenOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *GetSessionTokenOutput - if *v == nil { - sv = &GetSessionTokenOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("Credentials", t.Name.Local): - nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) - if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil { - return err - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} - -func awsAwsquery_deserializeOpDocumentGetWebIdentityTokenOutput(v **GetWebIdentityTokenOutput, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } - var sv *GetWebIdentityTokenOutput - if *v == nil { - sv = &GetWebIdentityTokenOutput{} - } else { - sv = *v - } - - for { - t, done, err := decoder.Token() - if err != nil { - return err - } - if done { - break - } - originalDecoder := decoder - decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) - switch { - case strings.EqualFold("Expiration", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - t, err := smithytime.ParseDateTime(xtv) - if err != nil { - return err - } - sv.Expiration = ptr.Time(t) - } - - case strings.EqualFold("WebIdentityToken", t.Name.Local): - val, err := decoder.Value() - if err != nil { - return err - } - if val == nil { - break - } - { - xtv := string(val) - sv.WebIdentityToken = ptr.String(xtv) - } - - default: - // Do nothing and ignore the unexpected tag element - err = decoder.Decoder.Skip() - if err != nil { - return err - } - - } - decoder = originalDecoder - } - *v = sv - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/doc.go deleted file mode 100644 index cbb19c7..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/doc.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -// Package sts provides the API client, operations, and parameter types for AWS -// Security Token Service. -// -// # Security Token Service -// -// Security Token Service (STS) enables you to request temporary, -// limited-privilege credentials for users. This guide provides descriptions of the -// STS API. For more information about using this service, see [Temporary Security Credentials]. -// -// [Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html -package sts diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go deleted file mode 100644 index c8f9526..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go +++ /dev/null @@ -1,1152 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "errors" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" - "github.com/aws/aws-sdk-go-v2/internal/endpoints" - "github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn" - internalendpoints "github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints" - smithy "github.com/aws/smithy-go" - smithyauth "github.com/aws/smithy-go/auth" - smithyendpoints "github.com/aws/smithy-go/endpoints" - "github.com/aws/smithy-go/endpoints/private/rulesfn" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/ptr" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net/http" - "net/url" - "os" - "strings" -) - -// EndpointResolverOptions is the service endpoint resolver options -type EndpointResolverOptions = internalendpoints.Options - -// EndpointResolver interface for resolving service endpoints. -type EndpointResolver interface { - ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error) -} - -var _ EndpointResolver = &internalendpoints.Resolver{} - -// NewDefaultEndpointResolver constructs a new service endpoint resolver -func NewDefaultEndpointResolver() *internalendpoints.Resolver { - return internalendpoints.New() -} - -// EndpointResolverFunc is a helper utility that wraps a function so it satisfies -// the EndpointResolver interface. This is useful when you want to add additional -// endpoint resolving logic, or stub out specific endpoints with custom values. -type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error) - -func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - return fn(region, options) -} - -// EndpointResolverFromURL returns an EndpointResolver configured using the -// provided endpoint url. By default, the resolved endpoint resolver uses the -// client region as signing region, and the endpoint source is set to -// EndpointSourceCustom.You can provide functional options to configure endpoint -// values for the resolved endpoint. -func EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver { - e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom} - for _, fn := range optFns { - fn(&e) - } - - return EndpointResolverFunc( - func(region string, options EndpointResolverOptions) (aws.Endpoint, error) { - if len(e.SigningRegion) == 0 { - e.SigningRegion = region - } - return e, nil - }, - ) -} - -type ResolveEndpoint struct { - Resolver EndpointResolver - Options EndpointResolverOptions -} - -func (*ResolveEndpoint) ID() string { - return "ResolveEndpoint" -} - -func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { - return next.HandleSerialize(ctx, in) - } - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.Resolver == nil { - return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") - } - - eo := m.Options - eo.Logger = middleware.GetLogger(ctx) - - var endpoint aws.Endpoint - endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo) - if err != nil { - nf := (&aws.EndpointNotFoundError{}) - if errors.As(err, &nf) { - ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false) - return next.HandleSerialize(ctx, in) - } - return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) - } - - req.URL, err = url.Parse(endpoint.URL) - if err != nil { - return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err) - } - - if len(awsmiddleware.GetSigningName(ctx)) == 0 { - signingName := endpoint.SigningName - if len(signingName) == 0 { - signingName = "sts" - } - ctx = awsmiddleware.SetSigningName(ctx, signingName) - } - ctx = awsmiddleware.SetEndpointSource(ctx, endpoint.Source) - ctx = smithyhttp.SetHostnameImmutable(ctx, endpoint.HostnameImmutable) - ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion) - ctx = awsmiddleware.SetPartitionID(ctx, endpoint.PartitionID) - return next.HandleSerialize(ctx, in) -} -func addResolveEndpointMiddleware(stack *middleware.Stack, o Options) error { - return stack.Serialize.Insert(&ResolveEndpoint{ - Resolver: o.EndpointResolver, - Options: o.EndpointOptions, - }, "OperationSerializer", middleware.Before) -} - -func removeResolveEndpointMiddleware(stack *middleware.Stack) error { - _, err := stack.Serialize.Remove((&ResolveEndpoint{}).ID()) - return err -} - -type wrappedEndpointResolver struct { - awsResolver aws.EndpointResolverWithOptions -} - -func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - return w.awsResolver.ResolveEndpoint(ServiceID, region, options) -} - -type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) - -func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) { - return a(service, region) -} - -var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) - -// withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error, -// and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked -// via its middleware. -// -// If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated. -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver { - var resolver aws.EndpointResolverWithOptions - - if awsResolverWithOptions != nil { - resolver = awsResolverWithOptions - } else if awsResolver != nil { - resolver = awsEndpointResolverAdaptor(awsResolver.ResolveEndpoint) - } - - return &wrappedEndpointResolver{ - awsResolver: resolver, - } -} - -func finalizeClientEndpointResolverOptions(options *Options) { - options.EndpointOptions.LogDeprecated = options.ClientLogMode.IsDeprecatedUsage() - - if len(options.EndpointOptions.ResolvedRegion) == 0 { - const fipsInfix = "-fips-" - const fipsPrefix = "fips-" - const fipsSuffix = "-fips" - - if strings.Contains(options.Region, fipsInfix) || - strings.Contains(options.Region, fipsPrefix) || - strings.Contains(options.Region, fipsSuffix) { - options.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( - options.Region, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") - options.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled - } - } - -} - -func resolveEndpointResolverV2(options *Options) { - if options.EndpointResolverV2 == nil { - options.EndpointResolverV2 = NewDefaultEndpointResolverV2() - } -} - -func resolveBaseEndpoint(cfg aws.Config, o *Options) { - if cfg.BaseEndpoint != nil { - o.BaseEndpoint = cfg.BaseEndpoint - } - - _, g := os.LookupEnv("AWS_ENDPOINT_URL") - _, s := os.LookupEnv("AWS_ENDPOINT_URL_STS") - - if g && !s { - return - } - - value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "STS", cfg.ConfigSources) - if found && err == nil { - o.BaseEndpoint = &value - } -} - -func bindRegion(region string) (*string, error) { - if region == "" { - return nil, nil - } - if !rulesfn.IsValidHostLabel(region, true) { - return nil, fmt.Errorf("invalid input region %s", region) - } - - return aws.String(endpoints.MapFIPSRegion(region)), nil -} - -// EndpointParameters provides the parameters that influence how endpoints are -// resolved. -type EndpointParameters struct { - // The AWS region used to dispatch the request. - // - // Parameter is - // required. - // - // AWS::Region - Region *string - - // When true, use the dual-stack endpoint. If the configured endpoint does not - // support dual-stack, dispatching the request MAY return an error. - // - // Defaults to - // false if no value is provided. - // - // AWS::UseDualStack - UseDualStack *bool - - // When true, send this request to the FIPS-compliant regional endpoint. If the - // configured endpoint does not have a FIPS compliant endpoint, dispatching the - // request will return an error. - // - // Defaults to false if no value is - // provided. - // - // AWS::UseFIPS - UseFIPS *bool - - // Override the endpoint used to send this request - // - // Parameter is - // required. - // - // SDK::Endpoint - Endpoint *string - - // Whether the global endpoint should be used, rather then the regional endpoint - // for us-east-1. - // - // Defaults to false if no value is - // provided. - // - // AWS::STS::UseGlobalEndpoint - UseGlobalEndpoint *bool -} - -// ValidateRequired validates required parameters are set. -func (p EndpointParameters) ValidateRequired() error { - if p.UseDualStack == nil { - return fmt.Errorf("parameter UseDualStack is required") - } - - if p.UseFIPS == nil { - return fmt.Errorf("parameter UseFIPS is required") - } - - if p.UseGlobalEndpoint == nil { - return fmt.Errorf("parameter UseGlobalEndpoint is required") - } - - return nil -} - -// WithDefaults returns a shallow copy of EndpointParameterswith default values -// applied to members where applicable. -func (p EndpointParameters) WithDefaults() EndpointParameters { - if p.UseDualStack == nil { - p.UseDualStack = ptr.Bool(false) - } - - if p.UseFIPS == nil { - p.UseFIPS = ptr.Bool(false) - } - - if p.UseGlobalEndpoint == nil { - p.UseGlobalEndpoint = ptr.Bool(false) - } - return p -} - -type stringSlice []string - -func (s stringSlice) Get(i int) *string { - if i < 0 || i >= len(s) { - return nil - } - - v := s[i] - return &v -} - -// EndpointResolverV2 provides the interface for resolving service endpoints. -type EndpointResolverV2 interface { - // ResolveEndpoint attempts to resolve the endpoint with the provided options, - // returning the endpoint if found. Otherwise an error is returned. - ResolveEndpoint(ctx context.Context, params EndpointParameters) ( - smithyendpoints.Endpoint, error, - ) -} - -// resolver provides the implementation for resolving endpoints. -type resolver struct{} - -func NewDefaultEndpointResolverV2() EndpointResolverV2 { - return &resolver{} -} - -// ResolveEndpoint attempts to resolve the endpoint with the provided options, -// returning the endpoint if found. Otherwise an error is returned. -func (r *resolver) ResolveEndpoint( - ctx context.Context, params EndpointParameters, -) ( - endpoint smithyendpoints.Endpoint, err error, -) { - params = params.WithDefaults() - if err = params.ValidateRequired(); err != nil { - return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) - } - _UseDualStack := *params.UseDualStack - _ = _UseDualStack - _UseFIPS := *params.UseFIPS - _ = _UseFIPS - _UseGlobalEndpoint := *params.UseGlobalEndpoint - _ = _UseGlobalEndpoint - - if _UseGlobalEndpoint == true { - if !(params.Endpoint != nil) { - if exprVal := params.Region; exprVal != nil { - _Region := *exprVal - _ = _Region - if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { - _PartitionResult := *exprVal - _ = _PartitionResult - if _UseFIPS == false { - if _UseDualStack == false { - if _Region == "ap-northeast-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "ap-south-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "ap-southeast-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "ap-southeast-2" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "aws-global" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "ca-central-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "eu-central-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "eu-north-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "eu-west-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "eu-west-2" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "eu-west-3" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "sa-east-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "us-east-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "us-east-2" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "us-west-1" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - if _Region == "us-west-2" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - uriString := func() string { - var out strings.Builder - out.WriteString("https://sts.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, _Region) - return sp - }(), - }, - }) - return out - }(), - }, nil - } - } - } - } - } - } - if exprVal := params.Endpoint; exprVal != nil { - _Endpoint := *exprVal - _ = _Endpoint - if _UseFIPS == true { - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported") - } - if _UseDualStack == true { - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported") - } - uriString := _Endpoint - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - if exprVal := params.Region; exprVal != nil { - _Region := *exprVal - _ = _Region - if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { - _PartitionResult := *exprVal - _ = _PartitionResult - if _UseFIPS == true { - if _UseDualStack == true { - if true == _PartitionResult.SupportsFIPS { - if true == _PartitionResult.SupportsDualStack { - uriString := func() string { - var out strings.Builder - out.WriteString("https://sts-fips.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DualStackDnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") - } - } - if _UseFIPS == true { - if _PartitionResult.SupportsFIPS == true { - if _PartitionResult.Name == "aws-us-gov" { - uriString := func() string { - var out strings.Builder - out.WriteString("https://sts.") - out.WriteString(_Region) - out.WriteString(".amazonaws.com") - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - uriString := func() string { - var out strings.Builder - out.WriteString("https://sts-fips.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS") - } - if _UseDualStack == true { - if true == _PartitionResult.SupportsDualStack { - uriString := func() string { - var out strings.Builder - out.WriteString("https://sts.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DualStackDnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack") - } - if _Region == "aws-global" { - uriString := "https://sts.amazonaws.com" - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - Properties: func() smithy.Properties { - var out smithy.Properties - smithyauth.SetAuthOptions(&out, []*smithyauth.Option{ - { - SchemeID: "aws.auth#sigv4", - SignerProperties: func() smithy.Properties { - var sp smithy.Properties - smithyhttp.SetSigV4SigningName(&sp, "sts") - smithyhttp.SetSigV4ASigningName(&sp, "sts") - - smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1") - return sp - }(), - }, - }) - return out - }(), - }, nil - } - uriString := func() string { - var out strings.Builder - out.WriteString("https://sts.") - out.WriteString(_Region) - out.WriteString(".") - out.WriteString(_PartitionResult.DnsSuffix) - return out.String() - }() - - uri, err := url.Parse(uriString) - if err != nil { - return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) - } - - return smithyendpoints.Endpoint{ - URI: *uri, - Headers: http.Header{}, - }, nil - } - return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") - } - return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region") -} - -type endpointParamsBinder interface { - bindEndpointParams(*EndpointParameters) -} - -func bindEndpointParams(ctx context.Context, input interface{}, options Options) (*EndpointParameters, error) { - params := &EndpointParameters{} - - region, err := bindRegion(options.Region) - if err != nil { - return nil, err - } - params.Region = region - - params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) - params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) - params.Endpoint = options.BaseEndpoint - - if b, ok := input.(endpointParamsBinder); ok { - b.bindEndpointParams(params) - } - - return params, nil -} - -type resolveEndpointV2Middleware struct { - options Options -} - -func (*resolveEndpointV2Middleware) ID() string { - return "ResolveEndpointV2" -} - -func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "ResolveEndpoint") - defer span.End() - - if awsmiddleware.GetRequiresLegacyEndpoints(ctx) { - return next.HandleFinalize(ctx, in) - } - - req, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - if m.options.EndpointResolverV2 == nil { - return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") - } - - params, err := bindEndpointParams(ctx, getOperationInput(ctx), m.options) - if err != nil { - return out, metadata, fmt.Errorf("failed to bind endpoint params, %w", err) - } - endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration", - func() (smithyendpoints.Endpoint, error) { - return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) - }) - if err != nil { - return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) - } - - span.SetProperty("client.call.resolved_endpoint", endpt.URI.String()) - - if endpt.URI.RawPath == "" && req.URL.RawPath != "" { - endpt.URI.RawPath = endpt.URI.Path - } - req.URL.Scheme = endpt.URI.Scheme - req.URL.Host = endpt.URI.Host - req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path) - req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath) - for k := range endpt.Headers { - req.Header.Set(k, endpt.Headers.Get(k)) - } - - rscheme := getResolvedAuthScheme(ctx) - if rscheme == nil { - return out, metadata, fmt.Errorf("no resolved auth scheme") - } - - opts, _ := smithyauth.GetAuthOptions(&endpt.Properties) - for _, o := range opts { - rscheme.SignerProperties.SetAll(&o.SignerProperties) - } - - span.End() - return next.HandleFinalize(ctx, in) -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json deleted file mode 100644 index e61823e..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "dependencies": { - "github.com/aws/aws-sdk-go-v2": "v1.4.0", - "github.com/aws/aws-sdk-go-v2/internal/configsources": "v0.0.0-00010101000000-000000000000", - "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2": "v2.0.0-00010101000000-000000000000", - "github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding": "v1.0.5", - "github.com/aws/aws-sdk-go-v2/service/internal/presigned-url": "v1.0.7", - "github.com/aws/smithy-go": "v1.4.0" - }, - "files": [ - "api_client.go", - "api_client_test.go", - "api_op_AssumeRole.go", - "api_op_AssumeRoleWithSAML.go", - "api_op_AssumeRoleWithWebIdentity.go", - "api_op_AssumeRoot.go", - "api_op_DecodeAuthorizationMessage.go", - "api_op_GetAccessKeyInfo.go", - "api_op_GetCallerIdentity.go", - "api_op_GetDelegatedAccessToken.go", - "api_op_GetFederationToken.go", - "api_op_GetSessionToken.go", - "api_op_GetWebIdentityToken.go", - "auth.go", - "deserializers.go", - "doc.go", - "endpoints.go", - "endpoints_config_test.go", - "endpoints_test.go", - "generated.json", - "internal/endpoints/endpoints.go", - "internal/endpoints/endpoints_test.go", - "options.go", - "protocol_test.go", - "serializers.go", - "snapshot_test.go", - "sra_operation_order_test.go", - "types/errors.go", - "types/types.go", - "validators.go" - ], - "go": "1.23", - "module": "github.com/aws/aws-sdk-go-v2/service/sts", - "unstable": false -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go deleted file mode 100644 index c081cde..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package sts - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.41.5" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go deleted file mode 100644 index be72d93..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go +++ /dev/null @@ -1,585 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package endpoints - -import ( - "github.com/aws/aws-sdk-go-v2/aws" - endpoints "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2" - "github.com/aws/smithy-go/logging" - "regexp" -) - -// Options is the endpoint resolver configuration options -type Options struct { - // Logger is a logging implementation that log events should be sent to. - Logger logging.Logger - - // LogDeprecated indicates that deprecated endpoints should be logged to the - // provided logger. - LogDeprecated bool - - // ResolvedRegion is used to override the region to be resolved, rather then the - // using the value passed to the ResolveEndpoint method. This value is used by the - // SDK to translate regions like fips-us-east-1 or us-east-1-fips to an alternative - // name. You must not set this value directly in your application. - ResolvedRegion string - - // DisableHTTPS informs the resolver to return an endpoint that does not use the - // HTTPS scheme. - DisableHTTPS bool - - // UseDualStackEndpoint specifies the resolver must resolve a dual-stack endpoint. - UseDualStackEndpoint aws.DualStackEndpointState - - // UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint. - UseFIPSEndpoint aws.FIPSEndpointState -} - -func (o Options) GetResolvedRegion() string { - return o.ResolvedRegion -} - -func (o Options) GetDisableHTTPS() bool { - return o.DisableHTTPS -} - -func (o Options) GetUseDualStackEndpoint() aws.DualStackEndpointState { - return o.UseDualStackEndpoint -} - -func (o Options) GetUseFIPSEndpoint() aws.FIPSEndpointState { - return o.UseFIPSEndpoint -} - -func transformToSharedOptions(options Options) endpoints.Options { - return endpoints.Options{ - Logger: options.Logger, - LogDeprecated: options.LogDeprecated, - ResolvedRegion: options.ResolvedRegion, - DisableHTTPS: options.DisableHTTPS, - UseDualStackEndpoint: options.UseDualStackEndpoint, - UseFIPSEndpoint: options.UseFIPSEndpoint, - } -} - -// Resolver STS endpoint resolver -type Resolver struct { - partitions endpoints.Partitions -} - -// ResolveEndpoint resolves the service endpoint for the given region and options -func (r *Resolver) ResolveEndpoint(region string, options Options) (endpoint aws.Endpoint, err error) { - if len(region) == 0 { - return endpoint, &aws.MissingRegionError{} - } - - opt := transformToSharedOptions(options) - return r.partitions.ResolveEndpoint(region, opt) -} - -// New returns a new Resolver -func New() *Resolver { - return &Resolver{ - partitions: defaultPartitions, - } -} - -var partitionRegexp = struct { - Aws *regexp.Regexp - AwsCn *regexp.Regexp - AwsEusc *regexp.Regexp - AwsIso *regexp.Regexp - AwsIsoB *regexp.Regexp - AwsIsoE *regexp.Regexp - AwsIsoF *regexp.Regexp - AwsUsGov *regexp.Regexp -}{ - - Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"), - AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), - AwsEusc: regexp.MustCompile("^eusc\\-(de)\\-\\w+\\-\\d+$"), - AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), - AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), - AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), - AwsIsoF: regexp.MustCompile("^us\\-isof\\-\\w+\\-\\d+$"), - AwsUsGov: regexp.MustCompile("^us\\-gov\\-\\w+\\-\\d+$"), -} - -var defaultPartitions = endpoints.Partitions{ - { - ID: "aws", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "sts.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "sts-fips.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "sts.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.Aws, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "af-south-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-east-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-northeast-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-northeast-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-northeast-3", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-south-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-south-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-3", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-4", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-5", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-6", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ap-southeast-7", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "aws-global", - }: endpoints.Endpoint{ - Hostname: "sts.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-east-1", - }, - }, - endpoints.EndpointKey{ - Region: "ca-central-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "ca-west-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-central-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-central-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-north-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-south-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-south-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-west-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-west-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "eu-west-3", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "il-central-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "me-central-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "me-south-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "mx-central-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "sa-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-east-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.us-east-1.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-east-1-fips", - }: endpoints.Endpoint{ - Hostname: "sts-fips.us-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-east-1", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "us-east-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-east-2", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.us-east-2.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-east-2-fips", - }: endpoints.Endpoint{ - Hostname: "sts-fips.us-east-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-east-2", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "us-west-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-west-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.us-west-1.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-west-1-fips", - }: endpoints.Endpoint{ - Hostname: "sts-fips.us-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-west-1", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "us-west-2", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-west-2", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.us-west-2.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-west-2-fips", - }: endpoints.Endpoint{ - Hostname: "sts-fips.us-west-2.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-west-2", - }, - Deprecated: aws.TrueTernary, - }, - }, - }, - { - ID: "aws-cn", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "sts.{region}.api.amazonwebservices.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.{region}.amazonaws.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "sts-fips.{region}.api.amazonwebservices.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "sts.{region}.amazonaws.com.cn", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsCn, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "cn-north-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "cn-northwest-1", - }: endpoints.Endpoint{}, - }, - }, - { - ID: "aws-eusc", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "sts.{region}.api.amazonwebservices.eu", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.{region}.amazonaws.eu", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "sts-fips.{region}.api.amazonwebservices.eu", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "sts.{region}.amazonaws.eu", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsEusc, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "eusc-de-east-1", - }: endpoints.Endpoint{}, - }, - }, - { - ID: "aws-iso", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.{region}.c2s.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "sts.{region}.c2s.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIso, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "us-iso-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-iso-west-1", - }: endpoints.Endpoint{}, - }, - }, - { - ID: "aws-iso-b", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.{region}.sc2s.sgov.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "sts.{region}.sc2s.sgov.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoB, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "us-isob-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-isob-west-1", - }: endpoints.Endpoint{}, - }, - }, - { - ID: "aws-iso-e", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.{region}.cloud.adc-e.uk", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "sts.{region}.cloud.adc-e.uk", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoE, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "eu-isoe-west-1", - }: endpoints.Endpoint{}, - }, - }, - { - ID: "aws-iso-f", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts-fips.{region}.csp.hci.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "sts.{region}.csp.hci.ic.gov", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsIsoF, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "us-isof-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-isof-south-1", - }: endpoints.Endpoint{}, - }, - }, - { - ID: "aws-us-gov", - Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ - { - Variant: endpoints.DualStackVariant, - }: { - Hostname: "sts.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, - }: { - Hostname: "sts-fips.{region}.api.aws", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - { - Variant: 0, - }: { - Hostname: "sts.{region}.amazonaws.com", - Protocols: []string{"https"}, - SignatureVersions: []string{"v4"}, - }, - }, - RegionRegex: partitionRegexp.AwsUsGov, - IsRegionalized: true, - Endpoints: endpoints.Endpoints{ - endpoints.EndpointKey{ - Region: "us-gov-east-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-gov-east-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts.us-gov-east-1.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-gov-east-1-fips", - }: endpoints.Endpoint{ - Hostname: "sts.us-gov-east-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-gov-east-1", - }, - Deprecated: aws.TrueTernary, - }, - endpoints.EndpointKey{ - Region: "us-gov-west-1", - }: endpoints.Endpoint{}, - endpoints.EndpointKey{ - Region: "us-gov-west-1", - Variant: endpoints.FIPSVariant, - }: { - Hostname: "sts.us-gov-west-1.amazonaws.com", - }, - endpoints.EndpointKey{ - Region: "us-gov-west-1-fips", - }: endpoints.Endpoint{ - Hostname: "sts.us-gov-west-1.amazonaws.com", - CredentialScope: endpoints.CredentialScope{ - Region: "us-gov-west-1", - }, - Deprecated: aws.TrueTernary, - }, - }, - }, -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go deleted file mode 100644 index f60b7d3..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go +++ /dev/null @@ -1,239 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "github.com/aws/aws-sdk-go-v2/aws" - awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" - smithyauth "github.com/aws/smithy-go/auth" - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "net/http" -) - -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) -} - -type Options struct { - // Set of options to modify how an operation is invoked. These apply to all - // operations invoked for this client. Use functional options on operation call to - // modify this list for per operation behavior. - APIOptions []func(*middleware.Stack) error - - // The optional application specific identifier appended to the User-Agent header. - AppID string - - // This endpoint will be given as input to an EndpointResolverV2. It is used for - // providing a custom base endpoint that is subject to modifications by the - // processing EndpointResolverV2. - BaseEndpoint *string - - // Configures the events that will be sent to the configured logger. - ClientLogMode aws.ClientLogMode - - // The credentials object to use when signing requests. - Credentials aws.CredentialsProvider - - // The configuration DefaultsMode that the SDK should use when constructing the - // clients initial default settings. - DefaultsMode aws.DefaultsMode - - // The endpoint options to be used when attempting to resolve an endpoint. - EndpointOptions EndpointResolverOptions - - // The service endpoint resolver. - // - // Deprecated: Deprecated: EndpointResolver and WithEndpointResolver. Providing a - // value for this field will likely prevent you from using any endpoint-related - // service features released after the introduction of EndpointResolverV2 and - // BaseEndpoint. - // - // To migrate an EndpointResolver implementation that uses a custom endpoint, set - // the client option BaseEndpoint instead. - EndpointResolver EndpointResolver - - // Resolves the endpoint used for a particular service operation. This should be - // used over the deprecated EndpointResolver. - EndpointResolverV2 EndpointResolverV2 - - // Signature Version 4 (SigV4) Signer - HTTPSignerV4 HTTPSignerV4 - - // The logger writer interface to write logging messages to. - Logger logging.Logger - - // The client meter provider. - MeterProvider metrics.MeterProvider - - // The region to send requests to. (Required) - Region string - - // RetryMaxAttempts specifies the maximum number attempts an API client will call - // an operation that fails with a retryable error. A value of 0 is ignored, and - // will not be used to configure the API client created default retryer, or modify - // per operation call's retry max attempts. - // - // If specified in an operation call's functional options with a value that is - // different than the constructed client's Options, the Client's Retryer will be - // wrapped to use the operation's specific RetryMaxAttempts value. - RetryMaxAttempts int - - // RetryMode specifies the retry mode the API client will be created with, if - // Retryer option is not also specified. - // - // When creating a new API Clients this member will only be used if the Retryer - // Options member is nil. This value will be ignored if Retryer is not nil. - // - // Currently does not support per operation call overrides, may in the future. - RetryMode aws.RetryMode - - // Retryer guides how HTTP requests should be retried in case of recoverable - // failures. When nil the API client will use a default retryer. The kind of - // default retry created by the API client can be changed with the RetryMode - // option. - Retryer aws.Retryer - - // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set - // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You - // should not populate this structure programmatically, or rely on the values here - // within your applications. - RuntimeEnvironment aws.RuntimeEnvironment - - // The client tracer provider. - TracerProvider tracing.TracerProvider - - // The initial DefaultsMode used when the client options were constructed. If the - // DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved - // value was at that point in time. - // - // Currently does not support per operation call overrides, may in the future. - resolvedDefaultsMode aws.DefaultsMode - - // The HTTP client to invoke API calls with. Defaults to client's default HTTP - // implementation if nil. - HTTPClient HTTPClient - - // Client registry of operation interceptors. - Interceptors smithyhttp.InterceptorRegistry - - // The auth scheme resolver which determines how to authenticate for each - // operation. - AuthSchemeResolver AuthSchemeResolver - - // The list of auth schemes supported by the client. - AuthSchemes []smithyhttp.AuthScheme - - // Priority list of preferred auth scheme names (e.g. sigv4a). - AuthSchemePreference []string -} - -// Copy creates a clone where the APIOptions list is deep copied. -func (o Options) Copy() Options { - to := o - to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) - copy(to.APIOptions, o.APIOptions) - to.Interceptors = o.Interceptors.Copy() - - return to -} - -func (o Options) GetIdentityResolver(schemeID string) smithyauth.IdentityResolver { - if schemeID == "aws.auth#sigv4" { - return getSigV4IdentityResolver(o) - } - if schemeID == "smithy.api#noAuth" { - return &smithyauth.AnonymousIdentityResolver{} - } - return nil -} - -// WithAPIOptions returns a functional option for setting the Client's APIOptions -// option. -func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { - return func(o *Options) { - o.APIOptions = append(o.APIOptions, optFns...) - } -} - -// Deprecated: EndpointResolver and WithEndpointResolver. Providing a value for -// this field will likely prevent you from using any endpoint-related service -// features released after the introduction of EndpointResolverV2 and BaseEndpoint. -// -// To migrate an EndpointResolver implementation that uses a custom endpoint, set -// the client option BaseEndpoint instead. -func WithEndpointResolver(v EndpointResolver) func(*Options) { - return func(o *Options) { - o.EndpointResolver = v - } -} - -// WithEndpointResolverV2 returns a functional option for setting the Client's -// EndpointResolverV2 option. -func WithEndpointResolverV2(v EndpointResolverV2) func(*Options) { - return func(o *Options) { - o.EndpointResolverV2 = v - } -} - -func getSigV4IdentityResolver(o Options) smithyauth.IdentityResolver { - if o.Credentials != nil { - return &internalauthsmithy.CredentialsProviderAdapter{Provider: o.Credentials} - } - return nil -} - -// WithSigV4SigningName applies an override to the authentication workflow to -// use the given signing name for SigV4-authenticated operations. -// -// This is an advanced setting. The value here is FINAL, taking precedence over -// the resolved signing name from both auth scheme resolution and endpoint -// resolution. -func WithSigV4SigningName(name string) func(*Options) { - fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, - ) { - return next.HandleInitialize(awsmiddleware.SetSigningName(ctx, name), in) - } - return func(o *Options) { - o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { - return s.Initialize.Add( - middleware.InitializeMiddlewareFunc("withSigV4SigningName", fn), - middleware.Before, - ) - }) - } -} - -// WithSigV4SigningRegion applies an override to the authentication workflow to -// use the given signing region for SigV4-authenticated operations. -// -// This is an advanced setting. The value here is FINAL, taking precedence over -// the resolved signing region from both auth scheme resolution and endpoint -// resolution. -func WithSigV4SigningRegion(region string) func(*Options) { - fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, - ) { - return next.HandleInitialize(awsmiddleware.SetSigningRegion(ctx, region), in) - } - return func(o *Options) { - o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { - return s.Initialize.Add( - middleware.InitializeMiddlewareFunc("withSigV4SigningRegion", fn), - middleware.Before, - ) - }) - } -} - -func ignoreAnonymousAuth(options *Options) { - if aws.IsCredentialsProvider(options.Credentials, (*aws.AnonymousCredentials)(nil)) { - options.Credentials = nil - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go deleted file mode 100644 index 5e22738..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go +++ /dev/null @@ -1,1198 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "bytes" - "context" - "fmt" - "github.com/aws/aws-sdk-go-v2/aws/protocol/query" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/encoding/httpbinding" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" - smithyhttp "github.com/aws/smithy-go/transport/http" - "path" -) - -type awsAwsquery_serializeOpAssumeRole struct { -} - -func (*awsAwsquery_serializeOpAssumeRole) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpAssumeRole) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*AssumeRoleInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("AssumeRole") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentAssumeRoleInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpAssumeRoleWithSAML struct { -} - -func (*awsAwsquery_serializeOpAssumeRoleWithSAML) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpAssumeRoleWithSAML) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*AssumeRoleWithSAMLInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("AssumeRoleWithSAML") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentAssumeRoleWithSAMLInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpAssumeRoleWithWebIdentity struct { -} - -func (*awsAwsquery_serializeOpAssumeRoleWithWebIdentity) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpAssumeRoleWithWebIdentity) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*AssumeRoleWithWebIdentityInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("AssumeRoleWithWebIdentity") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentAssumeRoleWithWebIdentityInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpAssumeRoot struct { -} - -func (*awsAwsquery_serializeOpAssumeRoot) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpAssumeRoot) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*AssumeRootInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("AssumeRoot") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentAssumeRootInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpDecodeAuthorizationMessage struct { -} - -func (*awsAwsquery_serializeOpDecodeAuthorizationMessage) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpDecodeAuthorizationMessage) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*DecodeAuthorizationMessageInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("DecodeAuthorizationMessage") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentDecodeAuthorizationMessageInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpGetAccessKeyInfo struct { -} - -func (*awsAwsquery_serializeOpGetAccessKeyInfo) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpGetAccessKeyInfo) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetAccessKeyInfoInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("GetAccessKeyInfo") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentGetAccessKeyInfoInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpGetCallerIdentity struct { -} - -func (*awsAwsquery_serializeOpGetCallerIdentity) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpGetCallerIdentity) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetCallerIdentityInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("GetCallerIdentity") - body.Key("Version").String("2011-06-15") - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpGetDelegatedAccessToken struct { -} - -func (*awsAwsquery_serializeOpGetDelegatedAccessToken) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpGetDelegatedAccessToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetDelegatedAccessTokenInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("GetDelegatedAccessToken") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentGetDelegatedAccessTokenInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpGetFederationToken struct { -} - -func (*awsAwsquery_serializeOpGetFederationToken) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpGetFederationToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetFederationTokenInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("GetFederationToken") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentGetFederationTokenInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpGetSessionToken struct { -} - -func (*awsAwsquery_serializeOpGetSessionToken) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpGetSessionToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetSessionTokenInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("GetSessionToken") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentGetSessionTokenInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} - -type awsAwsquery_serializeOpGetWebIdentityToken struct { -} - -func (*awsAwsquery_serializeOpGetWebIdentityToken) ID() string { - return "OperationSerializer" -} - -func (m *awsAwsquery_serializeOpGetWebIdentityToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - _, span := tracing.StartSpan(ctx, "OperationSerializer") - endTimer := startMetricTimer(ctx, "client.call.serialization_duration") - defer endTimer() - defer span.End() - request, ok := in.Request.(*smithyhttp.Request) - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} - } - - input, ok := in.Parameters.(*GetWebIdentityTokenInput) - _ = input - if !ok { - return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} - } - - operationPath := "/" - if len(request.Request.URL.Path) == 0 { - request.Request.URL.Path = operationPath - } else { - request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) - if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { - request.Request.URL.Path += "/" - } - } - request.Request.Method = "POST" - httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") - - bodyWriter := bytes.NewBuffer(nil) - bodyEncoder := query.NewEncoder(bodyWriter) - body := bodyEncoder.Object() - body.Key("Action").String("GetWebIdentityToken") - body.Key("Version").String("2011-06-15") - - if err := awsAwsquery_serializeOpDocumentGetWebIdentityTokenInput(input, bodyEncoder.Value); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - err = bodyEncoder.Encode() - if err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - - if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { - return out, metadata, &smithy.SerializationError{Err: err} - } - in.Request = request - - endTimer() - span.End() - return next.HandleSerialize(ctx, in) -} -func awsAwsquery_serializeDocumentPolicyDescriptorListType(v []types.PolicyDescriptorType, value query.Value) error { - array := value.Array("member") - - for i := range v { - av := array.Value() - if err := awsAwsquery_serializeDocumentPolicyDescriptorType(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsquery_serializeDocumentPolicyDescriptorType(v *types.PolicyDescriptorType, value query.Value) error { - object := value.Object() - _ = object - - if v.Arn != nil { - objectKey := object.Key("arn") - objectKey.String(*v.Arn) - } - - return nil -} - -func awsAwsquery_serializeDocumentProvidedContext(v *types.ProvidedContext, value query.Value) error { - object := value.Object() - _ = object - - if v.ContextAssertion != nil { - objectKey := object.Key("ContextAssertion") - objectKey.String(*v.ContextAssertion) - } - - if v.ProviderArn != nil { - objectKey := object.Key("ProviderArn") - objectKey.String(*v.ProviderArn) - } - - return nil -} - -func awsAwsquery_serializeDocumentProvidedContextsListType(v []types.ProvidedContext, value query.Value) error { - array := value.Array("member") - - for i := range v { - av := array.Value() - if err := awsAwsquery_serializeDocumentProvidedContext(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsquery_serializeDocumentTag(v *types.Tag, value query.Value) error { - object := value.Object() - _ = object - - if v.Key != nil { - objectKey := object.Key("Key") - objectKey.String(*v.Key) - } - - if v.Value != nil { - objectKey := object.Key("Value") - objectKey.String(*v.Value) - } - - return nil -} - -func awsAwsquery_serializeDocumentTagKeyListType(v []string, value query.Value) error { - array := value.Array("member") - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsquery_serializeDocumentTagListType(v []types.Tag, value query.Value) error { - array := value.Array("member") - - for i := range v { - av := array.Value() - if err := awsAwsquery_serializeDocumentTag(&v[i], av); err != nil { - return err - } - } - return nil -} - -func awsAwsquery_serializeDocumentWebIdentityTokenAudienceListType(v []string, value query.Value) error { - array := value.Array("member") - - for i := range v { - av := array.Value() - av.String(v[i]) - } - return nil -} - -func awsAwsquery_serializeOpDocumentAssumeRoleInput(v *AssumeRoleInput, value query.Value) error { - object := value.Object() - _ = object - - if v.DurationSeconds != nil { - objectKey := object.Key("DurationSeconds") - objectKey.Integer(*v.DurationSeconds) - } - - if v.ExternalId != nil { - objectKey := object.Key("ExternalId") - objectKey.String(*v.ExternalId) - } - - if v.Policy != nil { - objectKey := object.Key("Policy") - objectKey.String(*v.Policy) - } - - if v.PolicyArns != nil { - objectKey := object.Key("PolicyArns") - if err := awsAwsquery_serializeDocumentPolicyDescriptorListType(v.PolicyArns, objectKey); err != nil { - return err - } - } - - if v.ProvidedContexts != nil { - objectKey := object.Key("ProvidedContexts") - if err := awsAwsquery_serializeDocumentProvidedContextsListType(v.ProvidedContexts, objectKey); err != nil { - return err - } - } - - if v.RoleArn != nil { - objectKey := object.Key("RoleArn") - objectKey.String(*v.RoleArn) - } - - if v.RoleSessionName != nil { - objectKey := object.Key("RoleSessionName") - objectKey.String(*v.RoleSessionName) - } - - if v.SerialNumber != nil { - objectKey := object.Key("SerialNumber") - objectKey.String(*v.SerialNumber) - } - - if v.SourceIdentity != nil { - objectKey := object.Key("SourceIdentity") - objectKey.String(*v.SourceIdentity) - } - - if v.Tags != nil { - objectKey := object.Key("Tags") - if err := awsAwsquery_serializeDocumentTagListType(v.Tags, objectKey); err != nil { - return err - } - } - - if v.TokenCode != nil { - objectKey := object.Key("TokenCode") - objectKey.String(*v.TokenCode) - } - - if v.TransitiveTagKeys != nil { - objectKey := object.Key("TransitiveTagKeys") - if err := awsAwsquery_serializeDocumentTagKeyListType(v.TransitiveTagKeys, objectKey); err != nil { - return err - } - } - - return nil -} - -func awsAwsquery_serializeOpDocumentAssumeRoleWithSAMLInput(v *AssumeRoleWithSAMLInput, value query.Value) error { - object := value.Object() - _ = object - - if v.DurationSeconds != nil { - objectKey := object.Key("DurationSeconds") - objectKey.Integer(*v.DurationSeconds) - } - - if v.Policy != nil { - objectKey := object.Key("Policy") - objectKey.String(*v.Policy) - } - - if v.PolicyArns != nil { - objectKey := object.Key("PolicyArns") - if err := awsAwsquery_serializeDocumentPolicyDescriptorListType(v.PolicyArns, objectKey); err != nil { - return err - } - } - - if v.PrincipalArn != nil { - objectKey := object.Key("PrincipalArn") - objectKey.String(*v.PrincipalArn) - } - - if v.RoleArn != nil { - objectKey := object.Key("RoleArn") - objectKey.String(*v.RoleArn) - } - - if v.SAMLAssertion != nil { - objectKey := object.Key("SAMLAssertion") - objectKey.String(*v.SAMLAssertion) - } - - return nil -} - -func awsAwsquery_serializeOpDocumentAssumeRoleWithWebIdentityInput(v *AssumeRoleWithWebIdentityInput, value query.Value) error { - object := value.Object() - _ = object - - if v.DurationSeconds != nil { - objectKey := object.Key("DurationSeconds") - objectKey.Integer(*v.DurationSeconds) - } - - if v.Policy != nil { - objectKey := object.Key("Policy") - objectKey.String(*v.Policy) - } - - if v.PolicyArns != nil { - objectKey := object.Key("PolicyArns") - if err := awsAwsquery_serializeDocumentPolicyDescriptorListType(v.PolicyArns, objectKey); err != nil { - return err - } - } - - if v.ProviderId != nil { - objectKey := object.Key("ProviderId") - objectKey.String(*v.ProviderId) - } - - if v.RoleArn != nil { - objectKey := object.Key("RoleArn") - objectKey.String(*v.RoleArn) - } - - if v.RoleSessionName != nil { - objectKey := object.Key("RoleSessionName") - objectKey.String(*v.RoleSessionName) - } - - if v.WebIdentityToken != nil { - objectKey := object.Key("WebIdentityToken") - objectKey.String(*v.WebIdentityToken) - } - - return nil -} - -func awsAwsquery_serializeOpDocumentAssumeRootInput(v *AssumeRootInput, value query.Value) error { - object := value.Object() - _ = object - - if v.DurationSeconds != nil { - objectKey := object.Key("DurationSeconds") - objectKey.Integer(*v.DurationSeconds) - } - - if v.TargetPrincipal != nil { - objectKey := object.Key("TargetPrincipal") - objectKey.String(*v.TargetPrincipal) - } - - if v.TaskPolicyArn != nil { - objectKey := object.Key("TaskPolicyArn") - if err := awsAwsquery_serializeDocumentPolicyDescriptorType(v.TaskPolicyArn, objectKey); err != nil { - return err - } - } - - return nil -} - -func awsAwsquery_serializeOpDocumentDecodeAuthorizationMessageInput(v *DecodeAuthorizationMessageInput, value query.Value) error { - object := value.Object() - _ = object - - if v.EncodedMessage != nil { - objectKey := object.Key("EncodedMessage") - objectKey.String(*v.EncodedMessage) - } - - return nil -} - -func awsAwsquery_serializeOpDocumentGetAccessKeyInfoInput(v *GetAccessKeyInfoInput, value query.Value) error { - object := value.Object() - _ = object - - if v.AccessKeyId != nil { - objectKey := object.Key("AccessKeyId") - objectKey.String(*v.AccessKeyId) - } - - return nil -} - -func awsAwsquery_serializeOpDocumentGetCallerIdentityInput(v *GetCallerIdentityInput, value query.Value) error { - object := value.Object() - _ = object - - return nil -} - -func awsAwsquery_serializeOpDocumentGetDelegatedAccessTokenInput(v *GetDelegatedAccessTokenInput, value query.Value) error { - object := value.Object() - _ = object - - if v.TradeInToken != nil { - objectKey := object.Key("TradeInToken") - objectKey.String(*v.TradeInToken) - } - - return nil -} - -func awsAwsquery_serializeOpDocumentGetFederationTokenInput(v *GetFederationTokenInput, value query.Value) error { - object := value.Object() - _ = object - - if v.DurationSeconds != nil { - objectKey := object.Key("DurationSeconds") - objectKey.Integer(*v.DurationSeconds) - } - - if v.Name != nil { - objectKey := object.Key("Name") - objectKey.String(*v.Name) - } - - if v.Policy != nil { - objectKey := object.Key("Policy") - objectKey.String(*v.Policy) - } - - if v.PolicyArns != nil { - objectKey := object.Key("PolicyArns") - if err := awsAwsquery_serializeDocumentPolicyDescriptorListType(v.PolicyArns, objectKey); err != nil { - return err - } - } - - if v.Tags != nil { - objectKey := object.Key("Tags") - if err := awsAwsquery_serializeDocumentTagListType(v.Tags, objectKey); err != nil { - return err - } - } - - return nil -} - -func awsAwsquery_serializeOpDocumentGetSessionTokenInput(v *GetSessionTokenInput, value query.Value) error { - object := value.Object() - _ = object - - if v.DurationSeconds != nil { - objectKey := object.Key("DurationSeconds") - objectKey.Integer(*v.DurationSeconds) - } - - if v.SerialNumber != nil { - objectKey := object.Key("SerialNumber") - objectKey.String(*v.SerialNumber) - } - - if v.TokenCode != nil { - objectKey := object.Key("TokenCode") - objectKey.String(*v.TokenCode) - } - - return nil -} - -func awsAwsquery_serializeOpDocumentGetWebIdentityTokenInput(v *GetWebIdentityTokenInput, value query.Value) error { - object := value.Object() - _ = object - - if v.Audience != nil { - objectKey := object.Key("Audience") - if err := awsAwsquery_serializeDocumentWebIdentityTokenAudienceListType(v.Audience, objectKey); err != nil { - return err - } - } - - if v.DurationSeconds != nil { - objectKey := object.Key("DurationSeconds") - objectKey.Integer(*v.DurationSeconds) - } - - if v.SigningAlgorithm != nil { - objectKey := object.Key("SigningAlgorithm") - objectKey.String(*v.SigningAlgorithm) - } - - if v.Tags != nil { - objectKey := object.Key("Tags") - if err := awsAwsquery_serializeDocumentTagListType(v.Tags, objectKey); err != nil { - return err - } - } - - return nil -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go deleted file mode 100644 index 70d99a2..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go +++ /dev/null @@ -1,363 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - "fmt" - smithy "github.com/aws/smithy-go" -) - -// The web identity token that was passed is expired or is not valid. Get a new -// identity token from the identity provider and then retry the request. -type ExpiredTokenException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ExpiredTokenException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ExpiredTokenException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ExpiredTokenException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ExpiredTokenException" - } - return *e.ErrorCodeOverride -} -func (e *ExpiredTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The trade-in token provided in the request has expired and can no longer be -// exchanged for credentials. Request a new token and retry the operation. -type ExpiredTradeInTokenException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ExpiredTradeInTokenException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ExpiredTradeInTokenException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ExpiredTradeInTokenException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ExpiredTradeInTokenException" - } - return *e.ErrorCodeOverride -} -func (e *ExpiredTradeInTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The request could not be fulfilled because the identity provider (IDP) that was -// asked to verify the incoming identity token could not be reached. This is often -// a transient error caused by network conditions. Retry the request a limited -// number of times so that you don't exceed the request rate. If the error -// persists, the identity provider might be down or not responding. -type IDPCommunicationErrorException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *IDPCommunicationErrorException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *IDPCommunicationErrorException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *IDPCommunicationErrorException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "IDPCommunicationError" - } - return *e.ErrorCodeOverride -} -func (e *IDPCommunicationErrorException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The identity provider (IdP) reported that authentication failed. This might be -// because the claim is invalid. -// -// If this error is returned for the AssumeRoleWithWebIdentity operation, it can -// also mean that the claim has expired or has been explicitly revoked. -type IDPRejectedClaimException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *IDPRejectedClaimException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *IDPRejectedClaimException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *IDPRejectedClaimException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "IDPRejectedClaim" - } - return *e.ErrorCodeOverride -} -func (e *IDPRejectedClaimException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The error returned if the message passed to DecodeAuthorizationMessage was -// invalid. This can happen if the token contains invalid characters, such as line -// breaks, or if the message has expired. -type InvalidAuthorizationMessageException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidAuthorizationMessageException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidAuthorizationMessageException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidAuthorizationMessageException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidAuthorizationMessageException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidAuthorizationMessageException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The web identity token that was passed could not be validated by Amazon Web -// Services. Get a new identity token from the identity provider and then retry the -// request. -type InvalidIdentityTokenException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidIdentityTokenException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidIdentityTokenException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidIdentityTokenException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidIdentityToken" - } - return *e.ErrorCodeOverride -} -func (e *InvalidIdentityTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The requested token payload size exceeds the maximum allowed size. Reduce the -// number of request tags included in the GetWebIdentityToken API call to reduce -// the token payload size. -type JWTPayloadSizeExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *JWTPayloadSizeExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *JWTPayloadSizeExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *JWTPayloadSizeExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "JWTPayloadSizeExceededException" - } - return *e.ErrorCodeOverride -} -func (e *JWTPayloadSizeExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The request was rejected because the policy document was malformed. The error -// message describes the specific error. -type MalformedPolicyDocumentException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *MalformedPolicyDocumentException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *MalformedPolicyDocumentException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *MalformedPolicyDocumentException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "MalformedPolicyDocument" - } - return *e.ErrorCodeOverride -} -func (e *MalformedPolicyDocumentException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The outbound web identity federation feature is not enabled for this account. -// To use this feature, you must first enable it through the Amazon Web Services -// Management Console or API. -type OutboundWebIdentityFederationDisabledException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *OutboundWebIdentityFederationDisabledException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *OutboundWebIdentityFederationDisabledException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *OutboundWebIdentityFederationDisabledException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "OutboundWebIdentityFederationDisabledException" - } - return *e.ErrorCodeOverride -} -func (e *OutboundWebIdentityFederationDisabledException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The request was rejected because the total packed size of the session policies -// and session tags combined was too large. An Amazon Web Services conversion -// compresses the session policy document, session policy ARNs, and session tags -// into a packed binary format that has a separate limit. The error message -// indicates by percentage how close the policies and tags are to the upper size -// limit. For more information, see [Passing Session Tags in STS]in the IAM User Guide. -// -// You could receive this error even though you meet other defined session policy -// and session tag limits. For more information, see [IAM and STS Entity Character Limits]in the IAM User Guide. -// -// [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html -// [IAM and STS Entity Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html#reference_iam-limits-entity-length -type PackedPolicyTooLargeException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *PackedPolicyTooLargeException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *PackedPolicyTooLargeException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *PackedPolicyTooLargeException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "PackedPolicyTooLarge" - } - return *e.ErrorCodeOverride -} -func (e *PackedPolicyTooLargeException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// STS is not activated in the requested region for the account that is being -// asked to generate credentials. The account administrator must use the IAM -// console to activate STS in that region. For more information, see [Activating and Deactivating STS in an Amazon Web Services Region]in the IAM -// User Guide. -// -// [Activating and Deactivating STS in an Amazon Web Services Region]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-activate-deactivate -type RegionDisabledException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *RegionDisabledException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *RegionDisabledException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *RegionDisabledException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "RegionDisabledException" - } - return *e.ErrorCodeOverride -} -func (e *RegionDisabledException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The requested token duration would extend the session beyond its original -// expiration time. You cannot use this operation to extend the lifetime of a -// session beyond what was granted when the session was originally created. -type SessionDurationEscalationException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *SessionDurationEscalationException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *SessionDurationEscalationException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *SessionDurationEscalationException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "SessionDurationEscalationException" - } - return *e.ErrorCodeOverride -} -func (e *SessionDurationEscalationException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/types.go deleted file mode 100644 index dff7a3c..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/types.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - smithydocument "github.com/aws/smithy-go/document" - "time" -) - -// The identifiers for the temporary security credentials that the operation -// returns. -type AssumedRoleUser struct { - - // The ARN of the temporary security credentials that are returned from the AssumeRole - // action. For more information about ARNs and how to use them in policies, see [IAM Identifiers]in - // the IAM User Guide. - // - // [IAM Identifiers]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html - // - // This member is required. - Arn *string - - // A unique identifier that contains the role ID and the role session name of the - // role that is being assumed. The role ID is generated by Amazon Web Services when - // the role is created. - // - // This member is required. - AssumedRoleId *string - - noSmithyDocumentSerde -} - -// Amazon Web Services credentials for API authentication. -type Credentials struct { - - // The access key ID that identifies the temporary security credentials. - // - // This member is required. - AccessKeyId *string - - // The date on which the current credentials expire. - // - // This member is required. - Expiration *time.Time - - // The secret access key that can be used to sign requests. - // - // This member is required. - SecretAccessKey *string - - // The token that users must pass to the service API to use the temporary - // credentials. - // - // This member is required. - SessionToken *string - - noSmithyDocumentSerde -} - -// Identifiers for the federated user that is associated with the credentials. -type FederatedUser struct { - - // The ARN that specifies the federated user that is associated with the - // credentials. For more information about ARNs and how to use them in policies, - // see [IAM Identifiers]in the IAM User Guide. - // - // [IAM Identifiers]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html - // - // This member is required. - Arn *string - - // The string that identifies the federated user associated with the credentials, - // similar to the unique ID of an IAM user. - // - // This member is required. - FederatedUserId *string - - noSmithyDocumentSerde -} - -// A reference to the IAM managed policy that is passed as a session policy for a -// role session or a federated user session. -type PolicyDescriptorType struct { - - // The Amazon Resource Name (ARN) of the IAM managed policy to use as a session - // policy for the role. For more information about ARNs, see [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]in the Amazon Web - // Services General Reference. - // - // [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html - Arn *string - - noSmithyDocumentSerde -} - -// Contains information about the provided context. This includes the signed and -// encrypted trusted context assertion and the context provider ARN from which the -// trusted context assertion was generated. -type ProvidedContext struct { - - // The signed and encrypted trusted context assertion generated by the context - // provider. The trusted context assertion is signed and encrypted by Amazon Web - // Services STS. - ContextAssertion *string - - // The context provider ARN from which the trusted context assertion was generated. - ProviderArn *string - - noSmithyDocumentSerde -} - -// You can pass custom key-value pair attributes when you assume a role or -// federate a user. These are called session tags. You can then use the session -// tags to control access to resources. For more information, see [Tagging Amazon Web Services STS Sessions]in the IAM User -// Guide. -// -// [Tagging Amazon Web Services STS Sessions]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html -type Tag struct { - - // The key for a session tag. - // - // You can pass up to 50 session tags. The plain text session tag keys can’t - // exceed 128 characters. For these and additional limits, see [IAM and STS Character Limits]in the IAM User - // Guide. - // - // [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length - // - // This member is required. - Key *string - - // The value for a session tag. - // - // You can pass up to 50 session tags. The plain text session tag values can’t - // exceed 256 characters. For these and additional limits, see [IAM and STS Character Limits]in the IAM User - // Guide. - // - // [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -type noSmithyDocumentSerde = smithydocument.NoSerde diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go deleted file mode 100644 index 4d37dd2..0000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go +++ /dev/null @@ -1,433 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package sts - -import ( - "context" - "fmt" - "github.com/aws/aws-sdk-go-v2/service/sts/types" - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/middleware" -) - -type validateOpAssumeRole struct { -} - -func (*validateOpAssumeRole) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpAssumeRole) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*AssumeRoleInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpAssumeRoleInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpAssumeRoleWithSAML struct { -} - -func (*validateOpAssumeRoleWithSAML) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpAssumeRoleWithSAML) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*AssumeRoleWithSAMLInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpAssumeRoleWithSAMLInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpAssumeRoleWithWebIdentity struct { -} - -func (*validateOpAssumeRoleWithWebIdentity) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpAssumeRoleWithWebIdentity) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*AssumeRoleWithWebIdentityInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpAssumeRoleWithWebIdentityInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpAssumeRoot struct { -} - -func (*validateOpAssumeRoot) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpAssumeRoot) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*AssumeRootInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpAssumeRootInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpDecodeAuthorizationMessage struct { -} - -func (*validateOpDecodeAuthorizationMessage) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpDecodeAuthorizationMessage) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*DecodeAuthorizationMessageInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpDecodeAuthorizationMessageInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetAccessKeyInfo struct { -} - -func (*validateOpGetAccessKeyInfo) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetAccessKeyInfo) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetAccessKeyInfoInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetAccessKeyInfoInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetDelegatedAccessToken struct { -} - -func (*validateOpGetDelegatedAccessToken) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetDelegatedAccessToken) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetDelegatedAccessTokenInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetDelegatedAccessTokenInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetFederationToken struct { -} - -func (*validateOpGetFederationToken) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetFederationToken) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetFederationTokenInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetFederationTokenInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -type validateOpGetWebIdentityToken struct { -} - -func (*validateOpGetWebIdentityToken) ID() string { - return "OperationInputValidation" -} - -func (m *validateOpGetWebIdentityToken) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( - out middleware.InitializeOutput, metadata middleware.Metadata, err error, -) { - input, ok := in.Parameters.(*GetWebIdentityTokenInput) - if !ok { - return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) - } - if err := validateOpGetWebIdentityTokenInput(input); err != nil { - return out, metadata, err - } - return next.HandleInitialize(ctx, in) -} - -func addOpAssumeRoleValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpAssumeRole{}, middleware.After) -} - -func addOpAssumeRoleWithSAMLValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpAssumeRoleWithSAML{}, middleware.After) -} - -func addOpAssumeRoleWithWebIdentityValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpAssumeRoleWithWebIdentity{}, middleware.After) -} - -func addOpAssumeRootValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpAssumeRoot{}, middleware.After) -} - -func addOpDecodeAuthorizationMessageValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpDecodeAuthorizationMessage{}, middleware.After) -} - -func addOpGetAccessKeyInfoValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetAccessKeyInfo{}, middleware.After) -} - -func addOpGetDelegatedAccessTokenValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetDelegatedAccessToken{}, middleware.After) -} - -func addOpGetFederationTokenValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetFederationToken{}, middleware.After) -} - -func addOpGetWebIdentityTokenValidationMiddleware(stack *middleware.Stack) error { - return stack.Initialize.Add(&validateOpGetWebIdentityToken{}, middleware.After) -} - -func validateTag(v *types.Tag) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "Tag"} - if v.Key == nil { - invalidParams.Add(smithy.NewErrParamRequired("Key")) - } - if v.Value == nil { - invalidParams.Add(smithy.NewErrParamRequired("Value")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateTagListType(v []types.Tag) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "TagListType"} - for i := range v { - if err := validateTag(&v[i]); err != nil { - invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpAssumeRoleInput(v *AssumeRoleInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssumeRoleInput"} - if v.RoleArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("RoleArn")) - } - if v.RoleSessionName == nil { - invalidParams.Add(smithy.NewErrParamRequired("RoleSessionName")) - } - if v.Tags != nil { - if err := validateTagListType(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpAssumeRoleWithSAMLInput(v *AssumeRoleWithSAMLInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssumeRoleWithSAMLInput"} - if v.RoleArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("RoleArn")) - } - if v.PrincipalArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("PrincipalArn")) - } - if v.SAMLAssertion == nil { - invalidParams.Add(smithy.NewErrParamRequired("SAMLAssertion")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpAssumeRoleWithWebIdentityInput(v *AssumeRoleWithWebIdentityInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssumeRoleWithWebIdentityInput"} - if v.RoleArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("RoleArn")) - } - if v.RoleSessionName == nil { - invalidParams.Add(smithy.NewErrParamRequired("RoleSessionName")) - } - if v.WebIdentityToken == nil { - invalidParams.Add(smithy.NewErrParamRequired("WebIdentityToken")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpAssumeRootInput(v *AssumeRootInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "AssumeRootInput"} - if v.TargetPrincipal == nil { - invalidParams.Add(smithy.NewErrParamRequired("TargetPrincipal")) - } - if v.TaskPolicyArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("TaskPolicyArn")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpDecodeAuthorizationMessageInput(v *DecodeAuthorizationMessageInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "DecodeAuthorizationMessageInput"} - if v.EncodedMessage == nil { - invalidParams.Add(smithy.NewErrParamRequired("EncodedMessage")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetAccessKeyInfoInput(v *GetAccessKeyInfoInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetAccessKeyInfoInput"} - if v.AccessKeyId == nil { - invalidParams.Add(smithy.NewErrParamRequired("AccessKeyId")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetDelegatedAccessTokenInput(v *GetDelegatedAccessTokenInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetDelegatedAccessTokenInput"} - if v.TradeInToken == nil { - invalidParams.Add(smithy.NewErrParamRequired("TradeInToken")) - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetFederationTokenInput(v *GetFederationTokenInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetFederationTokenInput"} - if v.Name == nil { - invalidParams.Add(smithy.NewErrParamRequired("Name")) - } - if v.Tags != nil { - if err := validateTagListType(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} - -func validateOpGetWebIdentityTokenInput(v *GetWebIdentityTokenInput) error { - if v == nil { - return nil - } - invalidParams := smithy.InvalidParamsError{Context: "GetWebIdentityTokenInput"} - if v.Audience == nil { - invalidParams.Add(smithy.NewErrParamRequired("Audience")) - } - if v.SigningAlgorithm == nil { - invalidParams.Add(smithy.NewErrParamRequired("SigningAlgorithm")) - } - if v.Tags != nil { - if err := validateTagListType(v.Tags); err != nil { - invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) - } - } - if invalidParams.Len() > 0 { - return invalidParams - } else { - return nil - } -} diff --git a/vendor/github.com/aws/smithy-go/.gitignore b/vendor/github.com/aws/smithy-go/.gitignore deleted file mode 100644 index 2518b34..0000000 --- a/vendor/github.com/aws/smithy-go/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# Eclipse -.classpath -.project -.settings/ - -# Intellij -.idea/ -*.iml -*.iws - -# Mac -.DS_Store - -# Maven -target/ -**/dependency-reduced-pom.xml - -# Gradle -/.gradle -build/ -*/out/ -*/*/out/ - -# VS Code -bin/ -.vscode/ - -# make -c.out diff --git a/vendor/github.com/aws/smithy-go/.travis.yml b/vendor/github.com/aws/smithy-go/.travis.yml deleted file mode 100644 index f8d1035..0000000 --- a/vendor/github.com/aws/smithy-go/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -language: go -sudo: true -dist: bionic - -branches: - only: - - main - -os: - - linux - - osx - # Travis doesn't work with windows and Go tip - #- windows - -go: - - tip - -matrix: - allow_failures: - - go: tip - -before_install: - - if [ "$TRAVIS_OS_NAME" = "windows" ]; then choco install make; fi - - (cd /tmp/; go get golang.org/x/lint/golint) - -script: - - make go test -v ./...; - diff --git a/vendor/github.com/aws/smithy-go/CHANGELOG.md b/vendor/github.com/aws/smithy-go/CHANGELOG.md deleted file mode 100644 index 80af245..0000000 --- a/vendor/github.com/aws/smithy-go/CHANGELOG.md +++ /dev/null @@ -1,361 +0,0 @@ -# Release (2025-12-01) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.24.0 - * **Feature**: Improve allocation footprint of the middleware stack. This should convey a ~10% reduction in allocations per SDK request. - -# Release (2025-11-03) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.23.2 - * **Bug Fix**: Adjust the initial sizes of each middleware phase to avoid some unnecessary reallocation. - * **Bug Fix**: Avoid unnecessary allocation overhead from the metrics system when not in use. - -# Release (2025-10-15) - -## General Highlights -* **Dependency Update**: Bump minimum go version to 1.23. -* **Dependency Update**: Updated to the latest SDK module versions - -# Release (2025-09-18) - -## Module Highlights -* `github.com/aws/smithy-go/aws-http-auth`: [v1.1.0](aws-http-auth/CHANGELOG.md#v110-2025-09-18) - * **Feature**: Added support for SIG4/SIGV4A querystring authentication. - -# Release (2025-08-27) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.23.0 - * **Feature**: Sort map keys in JSON Document types. - -# Release (2025-07-24) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.22.5 - * **Feature**: Add HTTP interceptors. - -# Release (2025-06-16) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.22.4 - * **Bug Fix**: Fix CBOR serd empty check for string and enum fields - * **Bug Fix**: Fix HTTP metrics data race. - * **Bug Fix**: Replace usages of deprecated ioutil package. - -# Release (2025-02-17) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.22.3 - * **Dependency Update**: Bump minimum Go version to 1.22 per our language support policy. - -# Release (2025-01-21) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.22.2 - * **Bug Fix**: Fix HTTP metrics data race. - * **Bug Fix**: Replace usages of deprecated ioutil package. - -# Release (2024-11-15) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.22.1 - * **Bug Fix**: Fix failure to replace URI path segments when their names overlap. - -# Release (2024-10-03) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.22.0 - * **Feature**: Add HTTP client metrics. - -# Release (2024-09-25) - -## Module Highlights -* `github.com/aws/smithy-go/aws-http-auth`: [v1.0.0](aws-http-auth/CHANGELOG.md#v100-2024-09-25) - * **Release**: Initial release of module aws-http-auth, which implements generically consumable SigV4 and SigV4a request signing. - -# Release (2024-09-19) - -## General Highlights -* **Dependency Update**: Updated to the latest SDK module versions - -## Module Highlights -* `github.com/aws/smithy-go`: v1.21.0 - * **Feature**: Add tracing and metrics APIs, and builtin instrumentation for both, in generated clients. -* `github.com/aws/smithy-go/metrics/smithyotelmetrics`: [v1.0.0](metrics/smithyotelmetrics/CHANGELOG.md#v100-2024-09-19) - * **Release**: Initial release of `smithyotelmetrics` module, which is used to adapt an OpenTelemetry SDK meter provider to be used with Smithy clients. -* `github.com/aws/smithy-go/tracing/smithyoteltracing`: [v1.0.0](tracing/smithyoteltracing/CHANGELOG.md#v100-2024-09-19) - * **Release**: Initial release of `smithyoteltracing` module, which is used to adapt an OpenTelemetry SDK tracer provider to be used with Smithy clients. - -# Release (2024-08-14) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.20.4 - * **Dependency Update**: Bump minimum Go version to 1.21. - -# Release (2024-06-27) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.20.3 - * **Bug Fix**: Fix encoding/cbor test overflow on x86. - -# Release (2024-03-29) - -* No change notes available for this release. - -# Release (2024-02-21) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.20.1 - * **Bug Fix**: Remove runtime dependency on go-cmp. - -# Release (2024-02-13) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.20.0 - * **Feature**: Add codegen definition for sigv4a trait. - * **Feature**: Bump minimum Go version to 1.20 per our language support policy. - -# Release (2023-12-07) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.19.0 - * **Feature**: Support modeled request compression. - -# Release (2023-11-30) - -* No change notes available for this release. - -# Release (2023-11-29) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.18.0 - * **Feature**: Expose Options() method on generated service clients. - -# Release (2023-11-15) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.17.0 - * **Feature**: Support identity/auth components of client reference architecture. - -# Release (2023-10-31) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.16.0 - * **Feature**: **LANG**: Bump minimum go version to 1.19. - -# Release (2023-10-06) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.15.0 - * **Feature**: Add `http.WithHeaderComment` middleware. - -# Release (2023-08-18) - -* No change notes available for this release. - -# Release (2023-08-07) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.14.1 - * **Bug Fix**: Prevent duplicated error returns in EndpointResolverV2 default implementation. - -# Release (2023-07-31) - -## General Highlights -* **Feature**: Adds support for smithy-modeled endpoint resolution. - -# Release (2022-12-02) - -* No change notes available for this release. - -# Release (2022-10-24) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.13.4 - * **Bug Fix**: fixed document type checking for encoding nested types - -# Release (2022-09-14) - -* No change notes available for this release. - -# Release (v1.13.2) - -* No change notes available for this release. - -# Release (v1.13.1) - -* No change notes available for this release. - -# Release (v1.13.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.13.0 - * **Feature**: Adds support for the Smithy httpBearerAuth authentication trait to smithy-go. This allows the SDK to support the bearer authentication flow for API operations decorated with httpBearerAuth. An API client will need to be provided with its own bearer.TokenProvider implementation or use the bearer.StaticTokenProvider implementation. - -# Release (v1.12.1) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.12.1 - * **Bug Fix**: Fixes a bug where JSON object keys were not escaped. - -# Release (v1.12.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.12.0 - * **Feature**: `transport/http`: Add utility for setting context metadata when operation serializer automatically assigns content-type default value. - -# Release (v1.11.3) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.11.3 - * **Dependency Update**: Updates smithy-go unit test dependency go-cmp to 0.5.8. - -# Release (v1.11.2) - -* No change notes available for this release. - -# Release (v1.11.1) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.11.1 - * **Bug Fix**: Updates the smithy-go HTTP Request to correctly handle building the request to an http.Request. Related to [aws/aws-sdk-go-v2#1583](https://github.com/aws/aws-sdk-go-v2/issues/1583) - -# Release (v1.11.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.11.0 - * **Feature**: Updates deserialization of header list to supported quoted strings - -# Release (v1.10.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.10.0 - * **Feature**: Add `ptr.Duration`, `ptr.ToDuration`, `ptr.DurationSlice`, `ptr.ToDurationSlice`, `ptr.DurationMap`, and `ptr.ToDurationMap` functions for the `time.Duration` type. - -# Release (v1.9.1) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.9.1 - * **Documentation**: Fixes various typos in Go package documentation. - -# Release (v1.9.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.9.0 - * **Feature**: sync: OnceErr, can be used to concurrently record a signal when an error has occurred. - * **Bug Fix**: `transport/http`: CloseResponseBody and ErrorCloseResponseBody middleware have been updated to ensure that the body is fully drained before closing. - -# Release v1.8.1 - -### Smithy Go Module -* **Bug Fix**: Fixed an issue that would cause the HTTP Content-Length to be set to 0 if the stream body was not set. - * Fixes [aws/aws-sdk-go-v2#1418](https://github.com/aws/aws-sdk-go-v2/issues/1418) - -# Release v1.8.0 - -### Smithy Go Module - -* `time`: Add support for parsing additional DateTime timestamp format ([#324](https://github.com/aws/smithy-go/pull/324)) - * Adds support for parsing DateTime timestamp formatted time similar to RFC 3339, but without the `Z` character, nor UTC offset. - * Fixes [#1387](https://github.com/aws/aws-sdk-go-v2/issues/1387) - -# Release v1.7.0 - -### Smithy Go Module -* `ptr`: Handle error for deferred file close call ([#314](https://github.com/aws/smithy-go/pull/314)) - * Handle error for defer close call -* `middleware`: Add Clone to Metadata ([#318](https://github.com/aws/smithy-go/pull/318)) - * Adds a new Clone method to the middleware Metadata type. This provides a shallow clone of the entries in the Metadata. -* `document`: Add new package for document shape serialization support ([#310](https://github.com/aws/smithy-go/pull/310)) - -### Codegen -* Add Smithy Document Shape Support ([#310](https://github.com/aws/smithy-go/pull/310)) - * Adds support for Smithy Document shapes and supporting types for protocols to implement support - -# Release v1.6.0 (2021-07-15) - -### Smithy Go Module -* `encoding/httpbinding`: Support has been added for encoding `float32` and `float64` values that are `NaN`, `Infinity`, or `-Infinity`. ([#316](https://github.com/aws/smithy-go/pull/316)) - -### Codegen -* Adds support for handling `float32` and `float64` `NaN` values in HTTP Protocol Unit Tests. ([#316](https://github.com/aws/smithy-go/pull/316)) -* Adds support protocol generator implementations to override the error code string returned by `ErrorCode` methods on generated error types. ([#315](https://github.com/aws/smithy-go/pull/315)) - -# Release v1.5.0 (2021-06-25) - -### Smithy Go module -* `time`: Update time parsing to not be as strict for HTTPDate and DateTime ([#307](https://github.com/aws/smithy-go/pull/307)) - * Fixes [#302](https://github.com/aws/smithy-go/issues/302) by changing time to UTC before formatting so no local offset time is lost. - -### Codegen -* Adds support for integrating client members via plugins ([#301](https://github.com/aws/smithy-go/pull/301)) -* Fix serialization of enum types marked with payload trait ([#296](https://github.com/aws/smithy-go/pull/296)) -* Update generation of API client modules to include a manifest of files generated ([#283](https://github.com/aws/smithy-go/pull/283)) -* Update Group Java group ID for smithy-go generator ([#298](https://github.com/aws/smithy-go/pull/298)) -* Support the delegation of determining the errors that can occur for an operation ([#304](https://github.com/aws/smithy-go/pull/304)) -* Support for marking and documenting deprecated client config fields. ([#303](https://github.com/aws/smithy-go/pull/303)) - -# Release v1.4.0 (2021-05-06) - -### Smithy Go module -* `encoding/xml`: Fix escaping of Next Line and Line Start in XML Encoder ([#267](https://github.com/aws/smithy-go/pull/267)) - -### Codegen -* Add support for Smithy 1.7 ([#289](https://github.com/aws/smithy-go/pull/289)) -* Add support for httpQueryParams location -* Add support for model renaming conflict resolution with service closure - -# Release v1.3.1 (2021-04-08) - -### Smithy Go module -* `transport/http`: Loosen endpoint hostname validation to allow specifying port numbers. ([#279](https://github.com/aws/smithy-go/pull/279)) -* `io`: Fix RingBuffer panics due to out of bounds index. ([#282](https://github.com/aws/smithy-go/pull/282)) - -# Release v1.3.0 (2021-04-01) - -### Smithy Go module -* `transport/http`: Add utility to safely join string to url path, and url raw query. - -### Codegen -* Update HttpBindingProtocolGenerator to use http/transport JoinPath and JoinQuery utility. - -# Release v1.2.0 (2021-03-12) - -### Smithy Go module -* Fix support for parsing shortened year format in HTTP Date header. -* Fix GitHub APIDiff action workflow to get gorelease tool correctly. -* Fix codegen artifact unit test for Go 1.16 - -### Codegen -* Fix generating paginator nil parameter handling before usage. -* Fix Serialize unboxed members decorated as required. -* Add ability to define resolvers at both client construction and operation invocation. -* Support for extending paginators with custom runtime trait diff --git a/vendor/github.com/aws/smithy-go/CODE_OF_CONDUCT.md b/vendor/github.com/aws/smithy-go/CODE_OF_CONDUCT.md deleted file mode 100644 index 5b627cf..0000000 --- a/vendor/github.com/aws/smithy-go/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,4 +0,0 @@ -## Code of Conduct -This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). -For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact -opensource-codeofconduct@amazon.com with any additional questions or comments. diff --git a/vendor/github.com/aws/smithy-go/CONTRIBUTING.md b/vendor/github.com/aws/smithy-go/CONTRIBUTING.md deleted file mode 100644 index 1f8d01f..0000000 --- a/vendor/github.com/aws/smithy-go/CONTRIBUTING.md +++ /dev/null @@ -1,90 +0,0 @@ -# Contributing Guidelines - -Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional -documentation, we greatly value feedback and contributions from our community. - -Please read through this document before submitting any issues or pull requests to ensure we have all the necessary -information to effectively respond to your bug report or contribution. - - -## Reporting Bugs/Feature Requests - -We welcome you to use the GitHub issue tracker to report bugs or suggest features. - -When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already -reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: - -* A reproducible test case or series of steps -* The version of our code being used -* Any modifications you've made relevant to the bug -* Anything unusual about your environment or deployment - - -## Contributing via Pull Requests -Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: - -1. You are working against the latest source on the *main* branch. -2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. -3. You open an issue to discuss any significant work - we would hate for your time to be wasted. - -To send us a pull request, please: - -1. Fork the repository. -2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. -3. Ensure local tests pass. -4. Commit to your fork using clear commit messages. -5. Send us a pull request, answering any default questions in the pull request interface. -6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. - -GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and -[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). - -### Changelog Documents - -(You can SKIP this step if you are only changing the code generator, and not the runtime). - -When submitting a pull request please include a changelog file on a folder named `.changelog`. -These are used to generate the content `CHANGELOG.md` and Release Notes. The format of the file is as follows: - -``` -{ - "id": "12345678-1234-1234-1234-123456789012" - "type": "bugfix" - "collapse": true - "description": "Fix improper use of printf-style functions.", - "modules": [ - "." - ] -} -``` - -* id: a UUID. This should also be used for the name of the file, so if your id is `12345678-1234-1234-1234-123456789012` the file should be named `12345678-1234-1234-1234-123456789012.json/` -* type: one of the following: - * bugfix: Fixing an existing bug - * Feature: Adding a new feature to an existing service - * Release: Releasing a new module - * Dependency: Updating dependencies - * Announcement: Making an announcement, like deprecation of a module -* collapse: whether this change should appear separately on the release notes on every module listed on `modules` (`"collapse": false`), or if it should show up as a single entry (`"collapse": true`) - * For the smithy-go repository this should always be `false` -* description: Description of this change. Most of the times is the same as the title of the PR -* modules: which Go modules does this change impact. The root module is expressed as "." - - -## Finding contributions to work on -Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. - - -## Code of Conduct -This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). -For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact -opensource-codeofconduct@amazon.com with any additional questions or comments. - - -## Security issue notifications -If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. - - -## Licensing - -See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. diff --git a/vendor/github.com/aws/smithy-go/LICENSE b/vendor/github.com/aws/smithy-go/LICENSE deleted file mode 100644 index 67db858..0000000 --- a/vendor/github.com/aws/smithy-go/LICENSE +++ /dev/null @@ -1,175 +0,0 @@ - - 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. diff --git a/vendor/github.com/aws/smithy-go/Makefile b/vendor/github.com/aws/smithy-go/Makefile deleted file mode 100644 index a12b124..0000000 --- a/vendor/github.com/aws/smithy-go/Makefile +++ /dev/null @@ -1,130 +0,0 @@ -PRE_RELEASE_VERSION ?= - -RELEASE_MANIFEST_FILE ?= -RELEASE_CHGLOG_DESC_FILE ?= - -REPOTOOLS_VERSION ?= latest -REPOTOOLS_MODULE = github.com/awslabs/aws-go-multi-module-repository-tools -REPOTOOLS_CMD_CALCULATE_RELEASE = ${REPOTOOLS_MODULE}/cmd/calculaterelease@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_CALCULATE_RELEASE_ADDITIONAL_ARGS ?= -REPOTOOLS_CMD_UPDATE_REQUIRES = ${REPOTOOLS_MODULE}/cmd/updaterequires@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_UPDATE_MODULE_METADATA = ${REPOTOOLS_MODULE}/cmd/updatemodulemeta@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_GENERATE_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/generatechangelog@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/changelog@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_TAG_RELEASE = ${REPOTOOLS_MODULE}/cmd/tagrelease@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_MODULE_VERSION = ${REPOTOOLS_MODULE}/cmd/moduleversion@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_EACHMODULE = ${REPOTOOLS_MODULE}/cmd/eachmodule@${REPOTOOLS_VERSION} - -UNIT_TEST_TAGS= -BUILD_TAGS= - -ifneq ($(PRE_RELEASE_VERSION),) - REPOTOOLS_CMD_CALCULATE_RELEASE_ADDITIONAL_ARGS += -preview=${PRE_RELEASE_VERSION} -endif - -smithy-publish-local: - cd codegen && ./gradlew publishToMavenLocal - -smithy-build: - cd codegen && ./gradlew build - -smithy-clean: - cd codegen && ./gradlew clean - -GRADLE_RETRIES := 3 -GRADLE_SLEEP := 2 - -# We're making a call to ./gradlew to trigger downloading Gradle and -# starting the daemon. Any call works, so using `./gradlew help` -ensure-gradle-up: - @cd codegen && for i in $(shell seq 1 $(GRADLE_RETRIES)); do \ - echo "Checking if Gradle daemon is up, attempt $$i..."; \ - if ./gradlew help; then \ - echo "Gradle daemon is up!"; \ - exit 0; \ - fi; \ - echo "Failed to start Gradle, retrying in $(GRADLE_SLEEP) seconds..."; \ - sleep $(GRADLE_SLEEP); \ - done; \ - echo "Failed to start Gradle after $(GRADLE_RETRIES) attempts."; \ - exit 1 - -################## -# Linting/Verify # -################## -.PHONY: verify vet cover - -verify: vet - -vet: vet-modules-. - -vet-modules-%: - go run ${REPOTOOLS_CMD_EACHMODULE} -p $(subst vet-modules-,,$@) \ - "go vet ${BUILD_TAGS} --all ./..." - -cover: - go test ${BUILD_TAGS} -coverprofile c.out ./... - @cover=`go tool cover -func c.out | grep '^total:' | awk '{ print $$3+0 }'`; \ - echo "total (statements): $$cover%"; - -################ -# Unit Testing # -################ -.PHONY: test unit unit-race - -test: unit-race - -unit: verify unit-modules-. - -unit-modules-%: - go run ${REPOTOOLS_CMD_EACHMODULE} -p $(subst unit-modules-,,$@) \ - "go test -timeout=1m ${UNIT_TEST_TAGS} ./..." - -unit-race: verify unit-race-modules-. - -unit-race-modules-%: - go run ${REPOTOOLS_CMD_EACHMODULE} -p $(subst unit-race-modules-,,$@) \ - "go test -timeout=1m ${UNIT_TEST_TAGS} -race -cpu=4 ./..." - - -##################### -# Release Process # -##################### -.PHONY: preview-release pre-release-validation release - -preview-release: - go run ${REPOTOOLS_CMD_CALCULATE_RELEASE} ${REPOTOOLS_CMD_CALCULATE_RELEASE_ADDITIONAL_ARGS} - -pre-release-validation: - @if [[ -z "${RELEASE_MANIFEST_FILE}" ]]; then \ - echo "RELEASE_MANIFEST_FILE is required to specify the file to write the release manifest" && false; \ - fi - @if [[ -z "${RELEASE_CHGLOG_DESC_FILE}" ]]; then \ - echo "RELEASE_CHGLOG_DESC_FILE is required to specify the file to write the release notes" && false; \ - fi - -release: pre-release-validation - go run ${REPOTOOLS_CMD_CALCULATE_RELEASE} -o ${RELEASE_MANIFEST_FILE} ${REPOTOOLS_CMD_CALCULATE_RELEASE_ADDITIONAL_ARGS} - go run ${REPOTOOLS_CMD_UPDATE_REQUIRES} -release ${RELEASE_MANIFEST_FILE} - go run ${REPOTOOLS_CMD_UPDATE_MODULE_METADATA} -release ${RELEASE_MANIFEST_FILE} - go run ${REPOTOOLS_CMD_GENERATE_CHANGELOG} -release ${RELEASE_MANIFEST_FILE} -o ${RELEASE_CHGLOG_DESC_FILE} - go run ${REPOTOOLS_CMD_CHANGELOG} rm -all - go run ${REPOTOOLS_CMD_TAG_RELEASE} -release ${RELEASE_MANIFEST_FILE} - -module-version: - @go run ${REPOTOOLS_CMD_MODULE_VERSION} . - -############## -# Repo Tools # -############## -.PHONY: install-changelog - -external-changelog: - mkdir -p .changelog - cp changelog-template.json .changelog/00000000-0000-0000-0000-000000000000.json - @echo "Generate a new UUID and update the file at .changelog/00000000-0000-0000-0000-000000000000.json" - @echo "Make sure to rename the file with your new id, like .changelog/12345678-1234-1234-1234-123456789012.json" - @echo "See CONTRIBUTING.md 'Changelog Documents' and an example at https://github.com/aws/smithy-go/pull/543/files" - -install-changelog: - go install ${REPOTOOLS_MODULE}/cmd/changelog@${REPOTOOLS_VERSION} diff --git a/vendor/github.com/aws/smithy-go/NOTICE b/vendor/github.com/aws/smithy-go/NOTICE deleted file mode 100644 index 616fc58..0000000 --- a/vendor/github.com/aws/smithy-go/NOTICE +++ /dev/null @@ -1 +0,0 @@ -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/vendor/github.com/aws/smithy-go/README.md b/vendor/github.com/aws/smithy-go/README.md deleted file mode 100644 index ddce37b..0000000 --- a/vendor/github.com/aws/smithy-go/README.md +++ /dev/null @@ -1,100 +0,0 @@ -# Smithy Go - -[![Go Build Status](https://github.com/aws/smithy-go/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/aws/smithy-go/actions/workflows/go.yml)[![Codegen Build Status](https://github.com/aws/smithy-go/actions/workflows/codegen.yml/badge.svg?branch=main)](https://github.com/aws/smithy-go/actions/workflows/codegen.yml) - -[Smithy](https://smithy.io/) code generators for Go and the accompanying smithy-go runtime. - -The smithy-go runtime requires a minimum version of Go 1.23. - -**WARNING: All interfaces are subject to change.** - -## :no_entry_sign: DO NOT use the code generators in this repository - -**The code generators in this repository do not generate working clients at -this time.** - -In order to generate a usable smithy client you must provide a [protocol definition](https://github.com/aws/smithy-go/blob/main/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/ProtocolGenerator.java), -such as [AWS restJson1](https://smithy.io/2.0/aws/protocols/aws-restjson1-protocol.html), -in order to generate transport mechanisms and serialization/deserialization -code ("serde") accordingly. - -The code generator does not currently support any protocols out of the box. -Support for all [AWS protocols](https://smithy.io/2.0/aws/protocols/index.html) -exists in [aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2). We are -tracking the movement of those out of the SDK into smithy-go in -[#458](https://github.com/aws/smithy-go/issues/458), but there's currently no -timeline for doing so. - -## Plugins - -This repository implements the following Smithy build plugins: - -| ID | GAV prefix | Description | -|----|------------|-------------| -| `go-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go client code generation for Smithy models. | -| `go-server-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go server code generation for Smithy models. | -| `go-shape-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go shape code generation (types only) for Smithy models. | - -**NOTE: Build plugins are not currently published to mavenCentral. You must publish to mavenLocal to make the build plugins visible to the Smithy CLI. The artifact version is currently fixed at 0.1.0.** - -## `go-codegen` - -### Configuration - -[`GoSettings`](codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/GoSettings.java) -contains all of the settings enabled from `smithy-build.json` and helper -methods and types. The up-to-date list of top-level properties enabled for -`go-client-codegen` can be found in `GoSettings::from()`. - -| Setting | Type | Required | Description | -|-----------------|---------|----------|-----------------------------------------------------------------------------------------------------------------------------| -| `service` | string | yes | The Shape ID of the service for which to generate the client. | -| `module` | string | yes | Name of the module in `generated.json` (and `go.mod` if `generateGoMod` is enabled) and `doc.go`. | -| `generateGoMod` | boolean | | Whether to generate a default `go.mod` file. The default value is `false`. | -| `goDirective` | string | | [Go directive](https://go.dev/ref/mod#go-mod-file-go) of the module. The default value is the minimum supported Go version. | - -### Supported protocols - -| Protocol | Notes | -|----------|-------| -| [`smithy.protocols#rpcv2Cbor`](https://smithy.io/2.0/additional-specs/protocols/smithy-rpc-v2.html) | Event streaming not yet implemented. | - -### Example - -This example applies the `go-codegen` build plugin to the Smithy quickstart -example created from `smithy init`: - -```json -{ - "version": "1.0", - "sources": [ - "models" - ], - "maven": { - "dependencies": [ - "software.amazon.smithy.go:smithy-go-codegen:0.1.0" - ] - }, - "plugins": { - "go-codegen": { - "service": "example.weather#Weather", - "module": "github.com/example/weather", - "generateGoMod": true, - "goDirective": "1.23" - } - } -} -``` - -## `go-server-codegen` - -This plugin is a work-in-progress and is currently undocumented. - -## `go-shape-codegen` - -This plugin is a work-in-progress and is currently undocumented. - -## License - -This project is licensed under the Apache-2.0 License. - diff --git a/vendor/github.com/aws/smithy-go/auth/auth.go b/vendor/github.com/aws/smithy-go/auth/auth.go deleted file mode 100644 index 5bdb70c..0000000 --- a/vendor/github.com/aws/smithy-go/auth/auth.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package auth defines protocol-agnostic authentication types for smithy -// clients. -package auth diff --git a/vendor/github.com/aws/smithy-go/auth/bearer/docs.go b/vendor/github.com/aws/smithy-go/auth/bearer/docs.go deleted file mode 100644 index 1c9b971..0000000 --- a/vendor/github.com/aws/smithy-go/auth/bearer/docs.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package bearer provides middleware and utilities for authenticating API -// operation calls with a Bearer Token. -package bearer diff --git a/vendor/github.com/aws/smithy-go/auth/bearer/middleware.go b/vendor/github.com/aws/smithy-go/auth/bearer/middleware.go deleted file mode 100644 index 8c7d720..0000000 --- a/vendor/github.com/aws/smithy-go/auth/bearer/middleware.go +++ /dev/null @@ -1,104 +0,0 @@ -package bearer - -import ( - "context" - "fmt" - - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// Message is the middleware stack's request transport message value. -type Message interface{} - -// Signer provides an interface for implementations to decorate a request -// message with a bearer token. The signer is responsible for validating the -// message type is compatible with the signer. -type Signer interface { - SignWithBearerToken(context.Context, Token, Message) (Message, error) -} - -// AuthenticationMiddleware provides the Finalize middleware step for signing -// an request message with a bearer token. -type AuthenticationMiddleware struct { - signer Signer - tokenProvider TokenProvider -} - -// AddAuthenticationMiddleware helper adds the AuthenticationMiddleware to the -// middleware Stack in the Finalize step with the options provided. -func AddAuthenticationMiddleware(s *middleware.Stack, signer Signer, tokenProvider TokenProvider) error { - return s.Finalize.Add( - NewAuthenticationMiddleware(signer, tokenProvider), - middleware.After, - ) -} - -// NewAuthenticationMiddleware returns an initialized AuthenticationMiddleware. -func NewAuthenticationMiddleware(signer Signer, tokenProvider TokenProvider) *AuthenticationMiddleware { - return &AuthenticationMiddleware{ - signer: signer, - tokenProvider: tokenProvider, - } -} - -const authenticationMiddlewareID = "BearerTokenAuthentication" - -// ID returns the resolver identifier -func (m *AuthenticationMiddleware) ID() string { - return authenticationMiddlewareID -} - -// HandleFinalize implements the FinalizeMiddleware interface in order to -// update the request with bearer token authentication. -func (m *AuthenticationMiddleware) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, metadata middleware.Metadata, err error, -) { - token, err := m.tokenProvider.RetrieveBearerToken(ctx) - if err != nil { - return out, metadata, fmt.Errorf("failed AuthenticationMiddleware wrap message, %w", err) - } - - signedMessage, err := m.signer.SignWithBearerToken(ctx, token, in.Request) - if err != nil { - return out, metadata, fmt.Errorf("failed AuthenticationMiddleware sign message, %w", err) - } - - in.Request = signedMessage - return next.HandleFinalize(ctx, in) -} - -// SignHTTPSMessage provides a bearer token authentication implementation that -// will sign the message with the provided bearer token. -// -// Will fail if the message is not a smithy-go HTTP request or the request is -// not HTTPS. -type SignHTTPSMessage struct{} - -// NewSignHTTPSMessage returns an initialized signer for HTTP messages. -func NewSignHTTPSMessage() *SignHTTPSMessage { - return &SignHTTPSMessage{} -} - -// SignWithBearerToken returns a copy of the HTTP request with the bearer token -// added via the "Authorization" header, per RFC 6750, https://datatracker.ietf.org/doc/html/rfc6750. -// -// Returns an error if the request's URL scheme is not HTTPS, or the request -// message is not an smithy-go HTTP Request pointer type. -func (SignHTTPSMessage) SignWithBearerToken(ctx context.Context, token Token, message Message) (Message, error) { - req, ok := message.(*smithyhttp.Request) - if !ok { - return nil, fmt.Errorf("expect smithy-go HTTP Request, got %T", message) - } - - if !req.IsHTTPS() { - return nil, fmt.Errorf("bearer token with HTTP request requires HTTPS") - } - - reqClone := req.Clone() - reqClone.Header.Set("Authorization", "Bearer "+token.Value) - - return reqClone, nil -} diff --git a/vendor/github.com/aws/smithy-go/auth/bearer/token.go b/vendor/github.com/aws/smithy-go/auth/bearer/token.go deleted file mode 100644 index be260d4..0000000 --- a/vendor/github.com/aws/smithy-go/auth/bearer/token.go +++ /dev/null @@ -1,50 +0,0 @@ -package bearer - -import ( - "context" - "time" -) - -// Token provides a type wrapping a bearer token and expiration metadata. -type Token struct { - Value string - - CanExpire bool - Expires time.Time -} - -// Expired returns if the token's Expires time is before or equal to the time -// provided. If CanExpires is false, Expired will always return false. -func (t Token) Expired(now time.Time) bool { - if !t.CanExpire { - return false - } - now = now.Round(0) - return now.Equal(t.Expires) || now.After(t.Expires) -} - -// TokenProvider provides interface for retrieving bearer tokens. -type TokenProvider interface { - RetrieveBearerToken(context.Context) (Token, error) -} - -// TokenProviderFunc provides a helper utility to wrap a function as a type -// that implements the TokenProvider interface. -type TokenProviderFunc func(context.Context) (Token, error) - -// RetrieveBearerToken calls the wrapped function, returning the Token or -// error. -func (fn TokenProviderFunc) RetrieveBearerToken(ctx context.Context) (Token, error) { - return fn(ctx) -} - -// StaticTokenProvider provides a utility for wrapping a static bearer token -// value within an implementation of a token provider. -type StaticTokenProvider struct { - Token Token -} - -// RetrieveBearerToken returns the static token specified. -func (s StaticTokenProvider) RetrieveBearerToken(context.Context) (Token, error) { - return s.Token, nil -} diff --git a/vendor/github.com/aws/smithy-go/auth/bearer/token_cache.go b/vendor/github.com/aws/smithy-go/auth/bearer/token_cache.go deleted file mode 100644 index 223ddf5..0000000 --- a/vendor/github.com/aws/smithy-go/auth/bearer/token_cache.go +++ /dev/null @@ -1,208 +0,0 @@ -package bearer - -import ( - "context" - "fmt" - "sync/atomic" - "time" - - smithycontext "github.com/aws/smithy-go/context" - "github.com/aws/smithy-go/internal/sync/singleflight" -) - -// package variable that can be override in unit tests. -var timeNow = time.Now - -// TokenCacheOptions provides a set of optional configuration options for the -// TokenCache TokenProvider. -type TokenCacheOptions struct { - // The duration before the token will expire when the credentials will be - // refreshed. If DisableAsyncRefresh is true, the RetrieveBearerToken calls - // will be blocking. - // - // Asynchronous refreshes are deduplicated, and only one will be in-flight - // at a time. If the token expires while an asynchronous refresh is in - // flight, the next call to RetrieveBearerToken will block on that refresh - // to return. - RefreshBeforeExpires time.Duration - - // The timeout the underlying TokenProvider's RetrieveBearerToken call must - // return within, or will be canceled. Defaults to 0, no timeout. - // - // If 0 timeout, its possible for the underlying tokenProvider's - // RetrieveBearerToken call to block forever. Preventing subsequent - // TokenCache attempts to refresh the token. - // - // If this timeout is reached all pending deduplicated calls to - // TokenCache RetrieveBearerToken will fail with an error. - RetrieveBearerTokenTimeout time.Duration - - // The minimum duration between asynchronous refresh attempts. If the next - // asynchronous recent refresh attempt was within the minimum delay - // duration, the call to retrieve will return the current cached token, if - // not expired. - // - // The asynchronous retrieve is deduplicated across multiple calls when - // RetrieveBearerToken is called. The asynchronous retrieve is not a - // periodic task. It is only performed when the token has not yet expired, - // and the current item is within the RefreshBeforeExpires window, and the - // TokenCache's RetrieveBearerToken method is called. - // - // If 0, (default) there will be no minimum delay between asynchronous - // refresh attempts. - // - // If DisableAsyncRefresh is true, this option is ignored. - AsyncRefreshMinimumDelay time.Duration - - // Sets if the TokenCache will attempt to refresh the token in the - // background asynchronously instead of blocking for credentials to be - // refreshed. If disabled token refresh will be blocking. - // - // The first call to RetrieveBearerToken will always be blocking, because - // there is no cached token. - DisableAsyncRefresh bool -} - -// TokenCache provides an utility to cache Bearer Authentication tokens from a -// wrapped TokenProvider. The TokenCache can be has options to configure the -// cache's early and asynchronous refresh of the token. -type TokenCache struct { - options TokenCacheOptions - provider TokenProvider - - cachedToken atomic.Value - lastRefreshAttemptTime atomic.Value - sfGroup singleflight.Group -} - -// NewTokenCache returns a initialized TokenCache that implements the -// TokenProvider interface. Wrapping the provider passed in. Also taking a set -// of optional functional option parameters to configure the token cache. -func NewTokenCache(provider TokenProvider, optFns ...func(*TokenCacheOptions)) *TokenCache { - var options TokenCacheOptions - for _, fn := range optFns { - fn(&options) - } - - return &TokenCache{ - options: options, - provider: provider, - } -} - -// RetrieveBearerToken returns the token if it could be obtained, or error if a -// valid token could not be retrieved. -// -// The passed in Context's cancel/deadline/timeout will impacting only this -// individual retrieve call and not any other already queued up calls. This -// means underlying provider's RetrieveBearerToken calls could block for ever, -// and not be canceled with the Context. Set RetrieveBearerTokenTimeout to -// provide a timeout, preventing the underlying TokenProvider blocking forever. -// -// By default, if the passed in Context is canceled, all of its values will be -// considered expired. The wrapped TokenProvider will not be able to lookup the -// values from the Context once it is expired. This is done to protect against -// expired values no longer being valid. To disable this behavior, use -// smithy-go's context.WithPreserveExpiredValues to add a value to the Context -// before calling RetrieveBearerToken to enable support for expired values. -// -// Without RetrieveBearerTokenTimeout there is the potential for a underlying -// Provider's RetrieveBearerToken call to sit forever. Blocking in subsequent -// attempts at refreshing the token. -func (p *TokenCache) RetrieveBearerToken(ctx context.Context) (Token, error) { - cachedToken, ok := p.getCachedToken() - if !ok || cachedToken.Expired(timeNow()) { - return p.refreshBearerToken(ctx) - } - - // Check if the token should be refreshed before it expires. - refreshToken := cachedToken.Expired(timeNow().Add(p.options.RefreshBeforeExpires)) - if !refreshToken { - return cachedToken, nil - } - - if p.options.DisableAsyncRefresh { - return p.refreshBearerToken(ctx) - } - - p.tryAsyncRefresh(ctx) - - return cachedToken, nil -} - -// tryAsyncRefresh attempts to asynchronously refresh the token returning the -// already cached token. If it AsyncRefreshMinimumDelay option is not zero, and -// the duration since the last refresh is less than that value, nothing will be -// done. -func (p *TokenCache) tryAsyncRefresh(ctx context.Context) { - if p.options.AsyncRefreshMinimumDelay != 0 { - var lastRefreshAttempt time.Time - if v := p.lastRefreshAttemptTime.Load(); v != nil { - lastRefreshAttempt = v.(time.Time) - } - - if timeNow().Before(lastRefreshAttempt.Add(p.options.AsyncRefreshMinimumDelay)) { - return - } - } - - // Ignore the returned channel so this won't be blocking, and limit the - // number of additional goroutines created. - p.sfGroup.DoChan("async-refresh", func() (interface{}, error) { - res, err := p.refreshBearerToken(ctx) - if p.options.AsyncRefreshMinimumDelay != 0 { - var refreshAttempt time.Time - if err != nil { - refreshAttempt = timeNow() - } - p.lastRefreshAttemptTime.Store(refreshAttempt) - } - - return res, err - }) -} - -func (p *TokenCache) refreshBearerToken(ctx context.Context) (Token, error) { - resCh := p.sfGroup.DoChan("refresh-token", func() (interface{}, error) { - ctx := smithycontext.WithSuppressCancel(ctx) - if v := p.options.RetrieveBearerTokenTimeout; v != 0 { - var cancel func() - ctx, cancel = context.WithTimeout(ctx, v) - defer cancel() - } - return p.singleRetrieve(ctx) - }) - - select { - case res := <-resCh: - return res.Val.(Token), res.Err - case <-ctx.Done(): - return Token{}, fmt.Errorf("retrieve bearer token canceled, %w", ctx.Err()) - } -} - -func (p *TokenCache) singleRetrieve(ctx context.Context) (interface{}, error) { - token, err := p.provider.RetrieveBearerToken(ctx) - if err != nil { - return Token{}, fmt.Errorf("failed to retrieve bearer token, %w", err) - } - - p.cachedToken.Store(&token) - return token, nil -} - -// getCachedToken returns the currently cached token and true if found. Returns -// false if no token is cached. -func (p *TokenCache) getCachedToken() (Token, bool) { - v := p.cachedToken.Load() - if v == nil { - return Token{}, false - } - - t := v.(*Token) - if t == nil || t.Value == "" { - return Token{}, false - } - - return *t, true -} diff --git a/vendor/github.com/aws/smithy-go/auth/identity.go b/vendor/github.com/aws/smithy-go/auth/identity.go deleted file mode 100644 index ba8cf70..0000000 --- a/vendor/github.com/aws/smithy-go/auth/identity.go +++ /dev/null @@ -1,47 +0,0 @@ -package auth - -import ( - "context" - "time" - - "github.com/aws/smithy-go" -) - -// Identity contains information that identifies who the user making the -// request is. -type Identity interface { - Expiration() time.Time -} - -// IdentityResolver defines the interface through which an Identity is -// retrieved. -type IdentityResolver interface { - GetIdentity(context.Context, smithy.Properties) (Identity, error) -} - -// IdentityResolverOptions defines the interface through which an entity can be -// queried to retrieve an IdentityResolver for a given auth scheme. -type IdentityResolverOptions interface { - GetIdentityResolver(schemeID string) IdentityResolver -} - -// AnonymousIdentity is a sentinel to indicate no identity. -type AnonymousIdentity struct{} - -var _ Identity = (*AnonymousIdentity)(nil) - -// Expiration returns the zero value for time, as anonymous identity never -// expires. -func (*AnonymousIdentity) Expiration() time.Time { - return time.Time{} -} - -// AnonymousIdentityResolver returns AnonymousIdentity. -type AnonymousIdentityResolver struct{} - -var _ IdentityResolver = (*AnonymousIdentityResolver)(nil) - -// GetIdentity returns AnonymousIdentity. -func (*AnonymousIdentityResolver) GetIdentity(_ context.Context, _ smithy.Properties) (Identity, error) { - return &AnonymousIdentity{}, nil -} diff --git a/vendor/github.com/aws/smithy-go/auth/option.go b/vendor/github.com/aws/smithy-go/auth/option.go deleted file mode 100644 index d5dabff..0000000 --- a/vendor/github.com/aws/smithy-go/auth/option.go +++ /dev/null @@ -1,25 +0,0 @@ -package auth - -import "github.com/aws/smithy-go" - -type ( - authOptionsKey struct{} -) - -// Option represents a possible authentication method for an operation. -type Option struct { - SchemeID string - IdentityProperties smithy.Properties - SignerProperties smithy.Properties -} - -// GetAuthOptions gets auth Options from Properties. -func GetAuthOptions(p *smithy.Properties) ([]*Option, bool) { - v, ok := p.Get(authOptionsKey{}).([]*Option) - return v, ok -} - -// SetAuthOptions sets auth Options on Properties. -func SetAuthOptions(p *smithy.Properties, options []*Option) { - p.Set(authOptionsKey{}, options) -} diff --git a/vendor/github.com/aws/smithy-go/auth/scheme_id.go b/vendor/github.com/aws/smithy-go/auth/scheme_id.go deleted file mode 100644 index fb6a57c..0000000 --- a/vendor/github.com/aws/smithy-go/auth/scheme_id.go +++ /dev/null @@ -1,20 +0,0 @@ -package auth - -// Anonymous -const ( - SchemeIDAnonymous = "smithy.api#noAuth" -) - -// HTTP auth schemes -const ( - SchemeIDHTTPBasic = "smithy.api#httpBasicAuth" - SchemeIDHTTPDigest = "smithy.api#httpDigestAuth" - SchemeIDHTTPBearer = "smithy.api#httpBearerAuth" - SchemeIDHTTPAPIKey = "smithy.api#httpApiKeyAuth" -) - -// AWS auth schemes -const ( - SchemeIDSigV4 = "aws.auth#sigv4" - SchemeIDSigV4A = "aws.auth#sigv4a" -) diff --git a/vendor/github.com/aws/smithy-go/changelog-template.json b/vendor/github.com/aws/smithy-go/changelog-template.json deleted file mode 100644 index d36e2b3..0000000 --- a/vendor/github.com/aws/smithy-go/changelog-template.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "00000000-0000-0000-0000-000000000000", - "type": "feature|bugfix|dependency", - "description": "Description of your changes", - "collapse": false, - "modules": [ - "." - ] -} diff --git a/vendor/github.com/aws/smithy-go/context/suppress_expired.go b/vendor/github.com/aws/smithy-go/context/suppress_expired.go deleted file mode 100644 index a39b84a..0000000 --- a/vendor/github.com/aws/smithy-go/context/suppress_expired.go +++ /dev/null @@ -1,81 +0,0 @@ -package context - -import "context" - -// valueOnlyContext provides a utility to preserve only the values of a -// Context. Suppressing any cancellation or deadline on that context being -// propagated downstream of this value. -// -// If preserveExpiredValues is false (default), and the valueCtx is canceled, -// calls to lookup values with the Values method, will always return nil. Setting -// preserveExpiredValues to true, will allow the valueOnlyContext to lookup -// values in valueCtx even if valueCtx is canceled. -// -// Based on the Go standard libraries net/lookup.go onlyValuesCtx utility. -// https://github.com/golang/go/blob/da2773fe3e2f6106634673a38dc3a6eb875fe7d8/src/net/lookup.go -type valueOnlyContext struct { - context.Context - - preserveExpiredValues bool - valuesCtx context.Context -} - -var _ context.Context = (*valueOnlyContext)(nil) - -// Value looks up the key, returning its value. If configured to not preserve -// values of expired context, and the wrapping context is canceled, nil will be -// returned. -func (v *valueOnlyContext) Value(key interface{}) interface{} { - if !v.preserveExpiredValues { - select { - case <-v.valuesCtx.Done(): - return nil - default: - } - } - - return v.valuesCtx.Value(key) -} - -// WithSuppressCancel wraps the Context value, suppressing its deadline and -// cancellation events being propagated downstream to consumer of the returned -// context. -// -// By default the wrapped Context's Values are available downstream until the -// wrapped Context is canceled. Once the wrapped Context is canceled, Values -// method called on the context return will no longer lookup any key. As they -// are now considered expired. -// -// To override this behavior, use WithPreserveExpiredValues on the Context -// before it is wrapped by WithSuppressCancel. This will make the Context -// returned by WithSuppressCancel allow lookup of expired values. -func WithSuppressCancel(ctx context.Context) context.Context { - return &valueOnlyContext{ - Context: context.Background(), - valuesCtx: ctx, - - preserveExpiredValues: GetPreserveExpiredValues(ctx), - } -} - -type preserveExpiredValuesKey struct{} - -// WithPreserveExpiredValues adds a Value to the Context if expired values -// should be preserved, and looked up by a Context wrapped by -// WithSuppressCancel. -// -// WithPreserveExpiredValues must be added as a value to a Context, before that -// Context is wrapped by WithSuppressCancel -func WithPreserveExpiredValues(ctx context.Context, enable bool) context.Context { - return context.WithValue(ctx, preserveExpiredValuesKey{}, enable) -} - -// GetPreserveExpiredValues looks up, and returns the PreserveExpressValues -// value in the context. Returning true if enabled, false otherwise. -func GetPreserveExpiredValues(ctx context.Context) bool { - v := ctx.Value(preserveExpiredValuesKey{}) - if v != nil { - return v.(bool) - } - return false -} diff --git a/vendor/github.com/aws/smithy-go/doc.go b/vendor/github.com/aws/smithy-go/doc.go deleted file mode 100644 index 87b0c74..0000000 --- a/vendor/github.com/aws/smithy-go/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package smithy provides the core components for a Smithy SDK. -package smithy diff --git a/vendor/github.com/aws/smithy-go/document.go b/vendor/github.com/aws/smithy-go/document.go deleted file mode 100644 index dec498c..0000000 --- a/vendor/github.com/aws/smithy-go/document.go +++ /dev/null @@ -1,10 +0,0 @@ -package smithy - -// Document provides access to loosely structured data in a document-like -// format. -// -// Deprecated: See the github.com/aws/smithy-go/document package. -type Document interface { - UnmarshalDocument(interface{}) error - GetValue() (interface{}, error) -} diff --git a/vendor/github.com/aws/smithy-go/document/doc.go b/vendor/github.com/aws/smithy-go/document/doc.go deleted file mode 100644 index 03055b7..0000000 --- a/vendor/github.com/aws/smithy-go/document/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -// Package document provides interface definitions and error types for document types. -// -// A document is a protocol-agnostic type which supports a JSON-like data-model. You can use this type to send -// UTF-8 strings, arbitrary precision numbers, booleans, nulls, a list of these values, and a map of UTF-8 -// strings to these values. -// -// API Clients expose document constructors in their respective client document packages which must be used to -// Marshal and Unmarshal Go types to and from their respective protocol representations. -// -// See the Marshaler and Unmarshaler type documentation for more details on how to Go types can be converted to and from -// document types. -package document diff --git a/vendor/github.com/aws/smithy-go/document/document.go b/vendor/github.com/aws/smithy-go/document/document.go deleted file mode 100644 index 8f852d9..0000000 --- a/vendor/github.com/aws/smithy-go/document/document.go +++ /dev/null @@ -1,153 +0,0 @@ -package document - -import ( - "fmt" - "math/big" - "strconv" -) - -// Marshaler is an interface for a type that marshals a document to its protocol-specific byte representation and -// returns the resulting bytes. A non-nil error will be returned if an error is encountered during marshaling. -// -// Marshal supports basic scalars (int,uint,float,bool,string), big.Int, and big.Float, maps, slices, and structs. -// Anonymous nested types are flattened based on Go anonymous type visibility. -// -// When defining struct types. the `document` struct tag can be used to control how the value will be -// marshaled into the resulting protocol document. -// -// // Field is ignored -// Field int `document:"-"` -// -// // Field object of key "myName" -// Field int `document:"myName"` -// -// // Field object key of key "myName", and -// // Field is omitted if the field is a zero value for the type. -// Field int `document:"myName,omitempty"` -// -// // Field object key of "Field", and -// // Field is omitted if the field is a zero value for the type. -// Field int `document:",omitempty"` -// -// All struct fields, including anonymous fields, are marshaled unless the -// any of the following conditions are meet. -// -// - the field is not exported -// - document field tag is "-" -// - document field tag specifies "omitempty", and is a zero value. -// -// Pointer and interface values are encoded as the value pointed to or -// contained in the interface. A nil value encodes as a null -// value unless `omitempty` struct tag is provided. -// -// Channel, complex, and function values are not encoded and will be skipped -// when walking the value to be marshaled. -// -// time.Time is not supported and will cause the Marshaler to return an error. These values should be represented -// by your application as a string or numerical representation. -// -// Errors that occur when marshaling will stop the marshaler, and return the error. -// -// Marshal cannot represent cyclic data structures and will not handle them. -// Passing cyclic structures to Marshal will result in an infinite recursion. -type Marshaler interface { - MarshalSmithyDocument() ([]byte, error) -} - -// Unmarshaler is an interface for a type that unmarshals a document from its protocol-specific representation, and -// stores the result into the value pointed by v. If v is nil or not a pointer then InvalidUnmarshalError will be -// returned. -// -// Unmarshaler supports the same encodings produced by a document Marshaler. This includes support for the `document` -// struct field tag for controlling how struct fields are unmarshaled. -// -// Both generic interface{} and concrete types are valid unmarshal destination types. When unmarshaling a document -// into an empty interface the Unmarshaler will store one of these values: -// bool, for boolean values -// document.Number, for arbitrary-precision numbers (int64, float64, big.Int, big.Float) -// string, for string values -// []interface{}, for array values -// map[string]interface{}, for objects -// nil, for null values -// -// When unmarshaling, any error that occurs will halt the unmarshal and return the error. -type Unmarshaler interface { - UnmarshalSmithyDocument(v interface{}) error -} - -type noSerde interface { - noSmithyDocumentSerde() -} - -// NoSerde is a sentinel value to indicate that a given type should not be marshaled or unmarshaled -// into a protocol document. -type NoSerde struct{} - -func (n NoSerde) noSmithyDocumentSerde() {} - -var _ noSerde = (*NoSerde)(nil) - -// IsNoSerde returns whether the given type implements the no smithy document serde interface. -func IsNoSerde(x interface{}) bool { - _, ok := x.(noSerde) - return ok -} - -// Number is an arbitrary precision numerical value -type Number string - -// Int64 returns the number as a string. -func (n Number) String() string { - return string(n) -} - -// Int64 returns the number as an int64. -func (n Number) Int64() (int64, error) { - return n.intOfBitSize(64) -} - -func (n Number) intOfBitSize(bitSize int) (int64, error) { - return strconv.ParseInt(string(n), 10, bitSize) -} - -// Uint64 returns the number as a uint64. -func (n Number) Uint64() (uint64, error) { - return n.uintOfBitSize(64) -} - -func (n Number) uintOfBitSize(bitSize int) (uint64, error) { - return strconv.ParseUint(string(n), 10, bitSize) -} - -// Float32 returns the number parsed as a 32-bit float, returns a float64. -func (n Number) Float32() (float64, error) { - return n.floatOfBitSize(32) -} - -// Float64 returns the number as a float64. -func (n Number) Float64() (float64, error) { - return n.floatOfBitSize(64) -} - -// Float64 returns the number as a float64. -func (n Number) floatOfBitSize(bitSize int) (float64, error) { - return strconv.ParseFloat(string(n), bitSize) -} - -// BigFloat attempts to convert the number to a big.Float, returns an error if the operation fails. -func (n Number) BigFloat() (*big.Float, error) { - f, ok := (&big.Float{}).SetString(string(n)) - if !ok { - return nil, fmt.Errorf("failed to convert to big.Float") - } - return f, nil -} - -// BigInt attempts to convert the number to a big.Int, returns an error if the operation fails. -func (n Number) BigInt() (*big.Int, error) { - f, ok := (&big.Int{}).SetString(string(n), 10) - if !ok { - return nil, fmt.Errorf("failed to convert to big.Float") - } - return f, nil -} diff --git a/vendor/github.com/aws/smithy-go/document/errors.go b/vendor/github.com/aws/smithy-go/document/errors.go deleted file mode 100644 index 046a7a7..0000000 --- a/vendor/github.com/aws/smithy-go/document/errors.go +++ /dev/null @@ -1,75 +0,0 @@ -package document - -import ( - "fmt" - "reflect" -) - -// UnmarshalTypeError is an error type representing an error -// unmarshaling a Smithy document to a Go value type. This is different -// from UnmarshalError in that it does not wrap an underlying error type. -type UnmarshalTypeError struct { - Value string - Type reflect.Type -} - -// Error returns the string representation of the error. -// Satisfying the error interface. -func (e *UnmarshalTypeError) Error() string { - return fmt.Sprintf("unmarshal failed, cannot unmarshal %s into Go value type %s", - e.Value, e.Type.String()) -} - -// An InvalidUnmarshalError is an error type representing an invalid type -// encountered while unmarshaling a Smithy document to a Go value type. -type InvalidUnmarshalError struct { - Type reflect.Type -} - -// Error returns the string representation of the error. -// Satisfying the error interface. -func (e *InvalidUnmarshalError) Error() string { - var msg string - if e.Type == nil { - msg = "cannot unmarshal to nil value" - } else if e.Type.Kind() != reflect.Ptr { - msg = fmt.Sprintf("cannot unmarshal to non-pointer value, got %s", e.Type.String()) - } else { - msg = fmt.Sprintf("cannot unmarshal to nil value, %s", e.Type.String()) - } - - return fmt.Sprintf("unmarshal failed, %s", msg) -} - -// An UnmarshalError wraps an error that occurred while unmarshaling a -// Smithy document into a Go type. This is different from -// UnmarshalTypeError in that it wraps the underlying error that occurred. -type UnmarshalError struct { - Err error - Value string - Type reflect.Type -} - -// Unwrap returns the underlying unmarshaling error -func (e *UnmarshalError) Unwrap() error { - return e.Err -} - -// Error returns the string representation of the error. -// Satisfying the error interface. -func (e *UnmarshalError) Error() string { - return fmt.Sprintf("unmarshal failed, cannot unmarshal %q into %s, %v", - e.Value, e.Type.String(), e.Err) -} - -// An InvalidMarshalError is an error type representing an error -// occurring when marshaling a Go value type. -type InvalidMarshalError struct { - Message string -} - -// Error returns the string representation of the error. -// Satisfying the error interface. -func (e *InvalidMarshalError) Error() string { - return fmt.Sprintf("marshal failed, %s", e.Message) -} diff --git a/vendor/github.com/aws/smithy-go/encoding/doc.go b/vendor/github.com/aws/smithy-go/encoding/doc.go deleted file mode 100644 index 792fdfa..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package encoding provides utilities for encoding values for specific -// document encodings. - -package encoding diff --git a/vendor/github.com/aws/smithy-go/encoding/encoding.go b/vendor/github.com/aws/smithy-go/encoding/encoding.go deleted file mode 100644 index 2fdfb52..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/encoding.go +++ /dev/null @@ -1,40 +0,0 @@ -package encoding - -import ( - "fmt" - "math" - "strconv" -) - -// EncodeFloat encodes a float value as per the stdlib encoder for json and xml protocol -// This encodes a float value into dst while attempting to conform to ES6 ToString for Numbers -// -// Based on encoding/json floatEncoder from the Go Standard Library -// https://golang.org/src/encoding/json/encode.go -func EncodeFloat(dst []byte, v float64, bits int) []byte { - if math.IsInf(v, 0) || math.IsNaN(v) { - panic(fmt.Sprintf("invalid float value: %s", strconv.FormatFloat(v, 'g', -1, bits))) - } - - abs := math.Abs(v) - fmt := byte('f') - - if abs != 0 { - if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) { - fmt = 'e' - } - } - - dst = strconv.AppendFloat(dst, v, fmt, -1, bits) - - if fmt == 'e' { - // clean up e-09 to e-9 - n := len(dst) - if n >= 4 && dst[n-4] == 'e' && dst[n-3] == '-' && dst[n-2] == '0' { - dst[n-2] = dst[n-1] - dst = dst[:n-1] - } - } - - return dst -} diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go deleted file mode 100644 index 543e7cf..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go +++ /dev/null @@ -1,123 +0,0 @@ -package httpbinding - -import ( - "fmt" - "net/http" - "net/url" - "strconv" - "strings" -) - -const ( - contentLengthHeader = "Content-Length" - floatNaN = "NaN" - floatInfinity = "Infinity" - floatNegInfinity = "-Infinity" -) - -// An Encoder provides encoding of REST URI path, query, and header components -// of an HTTP request. Can also encode a stream as the payload. -// -// Does not support SetFields. -type Encoder struct { - path, rawPath, pathBuffer []byte - - query url.Values - header http.Header -} - -// NewEncoder creates a new encoder from the passed in request. It assumes that -// raw path contains no valuable information at this point, so it passes in path -// as path and raw path for subsequent trans -func NewEncoder(path, query string, headers http.Header) (*Encoder, error) { - return NewEncoderWithRawPath(path, path, query, headers) -} - -// NewHTTPBindingEncoder creates a new encoder from the passed in request. All query and -// header values will be added on top of the request's existing values. Overwriting -// duplicate values. -func NewEncoderWithRawPath(path, rawPath, query string, headers http.Header) (*Encoder, error) { - parseQuery, err := url.ParseQuery(query) - if err != nil { - return nil, fmt.Errorf("failed to parse query string: %w", err) - } - - e := &Encoder{ - path: []byte(path), - rawPath: []byte(rawPath), - query: parseQuery, - header: headers.Clone(), - } - - return e, nil -} - -// Encode returns a REST protocol encoder for encoding HTTP bindings. -// -// Due net/http requiring `Content-Length` to be specified on the http.Request#ContentLength directly. Encode -// will look for whether the header is present, and if so will remove it and set the respective value on http.Request. -// -// Returns any error occurring during encoding. -func (e *Encoder) Encode(req *http.Request) (*http.Request, error) { - req.URL.Path, req.URL.RawPath = string(e.path), string(e.rawPath) - req.URL.RawQuery = e.query.Encode() - - // net/http ignores Content-Length header and requires it to be set on http.Request - if v := e.header.Get(contentLengthHeader); len(v) > 0 { - iv, err := strconv.ParseInt(v, 10, 64) - if err != nil { - return nil, err - } - req.ContentLength = iv - e.header.Del(contentLengthHeader) - } - - req.Header = e.header - - return req, nil -} - -// AddHeader returns a HeaderValue for appending to the given header name -func (e *Encoder) AddHeader(key string) HeaderValue { - return newHeaderValue(e.header, key, true) -} - -// SetHeader returns a HeaderValue for setting the given header name -func (e *Encoder) SetHeader(key string) HeaderValue { - return newHeaderValue(e.header, key, false) -} - -// Headers returns a Header used for encoding headers with the given prefix -func (e *Encoder) Headers(prefix string) Headers { - return Headers{ - header: e.header, - prefix: strings.TrimSpace(prefix), - } -} - -// HasHeader returns if a header with the key specified exists with one or -// more value. -func (e Encoder) HasHeader(key string) bool { - return len(e.header[key]) != 0 -} - -// SetURI returns a URIValue used for setting the given path key -func (e *Encoder) SetURI(key string) URIValue { - return newURIValue(&e.path, &e.rawPath, &e.pathBuffer, key) -} - -// SetQuery returns a QueryValue used for setting the given query key -func (e *Encoder) SetQuery(key string) QueryValue { - return NewQueryValue(e.query, key, false) -} - -// AddQuery returns a QueryValue used for appending the given query key -func (e *Encoder) AddQuery(key string) QueryValue { - return NewQueryValue(e.query, key, true) -} - -// HasQuery returns if a query with the key specified exists with one or -// more values. -func (e *Encoder) HasQuery(key string) bool { - return len(e.query.Get(key)) != 0 -} diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go deleted file mode 100644 index f9256e1..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go +++ /dev/null @@ -1,122 +0,0 @@ -package httpbinding - -import ( - "encoding/base64" - "math" - "math/big" - "net/http" - "strconv" - "strings" -) - -// Headers is used to encode header keys using a provided prefix -type Headers struct { - header http.Header - prefix string -} - -// AddHeader returns a HeaderValue used to append values to prefix+key -func (h Headers) AddHeader(key string) HeaderValue { - return h.newHeaderValue(key, true) -} - -// SetHeader returns a HeaderValue used to set the value of prefix+key -func (h Headers) SetHeader(key string) HeaderValue { - return h.newHeaderValue(key, false) -} - -func (h Headers) newHeaderValue(key string, append bool) HeaderValue { - return newHeaderValue(h.header, h.prefix+strings.TrimSpace(key), append) -} - -// HeaderValue is used to encode values to an HTTP header -type HeaderValue struct { - header http.Header - key string - append bool -} - -func newHeaderValue(header http.Header, key string, append bool) HeaderValue { - return HeaderValue{header: header, key: strings.TrimSpace(key), append: append} -} - -func (h HeaderValue) modifyHeader(value string) { - if h.append { - h.header[h.key] = append(h.header[h.key], value) - } else { - h.header[h.key] = append(h.header[h.key][:0], value) - } -} - -// String encodes the value v as the header string value -func (h HeaderValue) String(v string) { - h.modifyHeader(v) -} - -// Byte encodes the value v as a query string value -func (h HeaderValue) Byte(v int8) { - h.Long(int64(v)) -} - -// Short encodes the value v as a query string value -func (h HeaderValue) Short(v int16) { - h.Long(int64(v)) -} - -// Integer encodes the value v as the header string value -func (h HeaderValue) Integer(v int32) { - h.Long(int64(v)) -} - -// Long encodes the value v as the header string value -func (h HeaderValue) Long(v int64) { - h.modifyHeader(strconv.FormatInt(v, 10)) -} - -// Boolean encodes the value v as a query string value -func (h HeaderValue) Boolean(v bool) { - h.modifyHeader(strconv.FormatBool(v)) -} - -// Float encodes the value v as a query string value -func (h HeaderValue) Float(v float32) { - h.float(float64(v), 32) -} - -// Double encodes the value v as a query string value -func (h HeaderValue) Double(v float64) { - h.float(v, 64) -} - -func (h HeaderValue) float(v float64, bitSize int) { - switch { - case math.IsNaN(v): - h.String(floatNaN) - case math.IsInf(v, 1): - h.String(floatInfinity) - case math.IsInf(v, -1): - h.String(floatNegInfinity) - default: - h.modifyHeader(strconv.FormatFloat(v, 'f', -1, bitSize)) - } -} - -// BigInteger encodes the value v as a query string value -func (h HeaderValue) BigInteger(v *big.Int) { - h.modifyHeader(v.String()) -} - -// BigDecimal encodes the value v as a query string value -func (h HeaderValue) BigDecimal(v *big.Float) { - if i, accuracy := v.Int64(); accuracy == big.Exact { - h.Long(i) - return - } - h.modifyHeader(v.Text('e', -1)) -} - -// Blob encodes the value v as a base64 header string value -func (h HeaderValue) Blob(v []byte) { - encodeToString := base64.StdEncoding.EncodeToString(v) - h.modifyHeader(encodeToString) -} diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go deleted file mode 100644 index 9ae3085..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go +++ /dev/null @@ -1,108 +0,0 @@ -package httpbinding - -import ( - "bytes" - "fmt" -) - -const ( - uriTokenStart = '{' - uriTokenStop = '}' - uriTokenSkip = '+' -) - -func bufCap(b []byte, n int) []byte { - if cap(b) < n { - return make([]byte, 0, n) - } - - return b[0:0] -} - -// replacePathElement replaces a single element in the path []byte. -// Escape is used to control whether the value will be escaped using Amazon path escape style. -func replacePathElement(path, fieldBuf []byte, key, val string, escape bool) ([]byte, []byte, error) { - // search for "{}". If not found, search for the greedy version "{+}". If none are found, return error - fieldBuf = bufCap(fieldBuf, len(key)+2) // { } - fieldBuf = append(fieldBuf, uriTokenStart) - fieldBuf = append(fieldBuf, key...) - fieldBuf = append(fieldBuf, uriTokenStop) - - start := bytes.Index(path, fieldBuf) - encodeSep := true - if start < 0 { - fieldBuf = bufCap(fieldBuf, len(key)+3) // { [+] } - fieldBuf = append(fieldBuf, uriTokenStart) - fieldBuf = append(fieldBuf, key...) - fieldBuf = append(fieldBuf, uriTokenSkip) - fieldBuf = append(fieldBuf, uriTokenStop) - - start = bytes.Index(path, fieldBuf) - if start < 0 { - return path, fieldBuf, fmt.Errorf("invalid path index, start=%d. %s", start, path) - } - encodeSep = false - } - end := start + len(fieldBuf) - - if escape { - val = EscapePath(val, encodeSep) - } - - fieldBuf = bufCap(fieldBuf, len(val)) - fieldBuf = append(fieldBuf, val...) - - keyLen := end - start - valLen := len(fieldBuf) - - if keyLen == valLen { - copy(path[start:], fieldBuf) - return path, fieldBuf, nil - } - - newLen := len(path) + (valLen - keyLen) - if len(path) < newLen { - path = path[:cap(path)] - } - if cap(path) < newLen { - newURI := make([]byte, newLen) - copy(newURI, path) - path = newURI - } - - // shift - copy(path[start+valLen:], path[end:]) - path = path[:newLen] - copy(path[start:], fieldBuf) - - return path, fieldBuf, nil -} - -// EscapePath escapes part of a URL path in Amazon style. -func EscapePath(path string, encodeSep bool) string { - var buf bytes.Buffer - for i := 0; i < len(path); i++ { - c := path[i] - if noEscape[c] || (c == '/' && !encodeSep) { - buf.WriteByte(c) - } else { - fmt.Fprintf(&buf, "%%%02X", c) - } - } - return buf.String() -} - -var noEscape [256]bool - -func init() { - for i := 0; i < len(noEscape); i++ { - // AWS expects every character except these to be escaped - noEscape[i] = (i >= 'A' && i <= 'Z') || - (i >= 'a' && i <= 'z') || - (i >= '0' && i <= '9') || - i == '-' || - i == '.' || - i == '_' || - i == '~' - } -} diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go deleted file mode 100644 index c2e7d0a..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go +++ /dev/null @@ -1,107 +0,0 @@ -package httpbinding - -import ( - "encoding/base64" - "math" - "math/big" - "net/url" - "strconv" -) - -// QueryValue is used to encode query key values -type QueryValue struct { - query url.Values - key string - append bool -} - -// NewQueryValue creates a new QueryValue which enables encoding -// a query value into the given url.Values. -func NewQueryValue(query url.Values, key string, append bool) QueryValue { - return QueryValue{ - query: query, - key: key, - append: append, - } -} - -func (qv QueryValue) updateKey(value string) { - if qv.append { - qv.query.Add(qv.key, value) - } else { - qv.query.Set(qv.key, value) - } -} - -// Blob encodes v as a base64 query string value -func (qv QueryValue) Blob(v []byte) { - encodeToString := base64.StdEncoding.EncodeToString(v) - qv.updateKey(encodeToString) -} - -// Boolean encodes v as a query string value -func (qv QueryValue) Boolean(v bool) { - qv.updateKey(strconv.FormatBool(v)) -} - -// String encodes v as a query string value -func (qv QueryValue) String(v string) { - qv.updateKey(v) -} - -// Byte encodes v as a query string value -func (qv QueryValue) Byte(v int8) { - qv.Long(int64(v)) -} - -// Short encodes v as a query string value -func (qv QueryValue) Short(v int16) { - qv.Long(int64(v)) -} - -// Integer encodes v as a query string value -func (qv QueryValue) Integer(v int32) { - qv.Long(int64(v)) -} - -// Long encodes v as a query string value -func (qv QueryValue) Long(v int64) { - qv.updateKey(strconv.FormatInt(v, 10)) -} - -// Float encodes v as a query string value -func (qv QueryValue) Float(v float32) { - qv.float(float64(v), 32) -} - -// Double encodes v as a query string value -func (qv QueryValue) Double(v float64) { - qv.float(v, 64) -} - -func (qv QueryValue) float(v float64, bitSize int) { - switch { - case math.IsNaN(v): - qv.String(floatNaN) - case math.IsInf(v, 1): - qv.String(floatInfinity) - case math.IsInf(v, -1): - qv.String(floatNegInfinity) - default: - qv.updateKey(strconv.FormatFloat(v, 'f', -1, bitSize)) - } -} - -// BigInteger encodes v as a query string value -func (qv QueryValue) BigInteger(v *big.Int) { - qv.updateKey(v.String()) -} - -// BigDecimal encodes v as a query string value -func (qv QueryValue) BigDecimal(v *big.Float) { - if i, accuracy := v.Int64(); accuracy == big.Exact { - qv.Long(i) - return - } - qv.updateKey(v.Text('e', -1)) -} diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go deleted file mode 100644 index f04e119..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go +++ /dev/null @@ -1,111 +0,0 @@ -package httpbinding - -import ( - "math" - "math/big" - "strconv" - "strings" -) - -// URIValue is used to encode named URI parameters -type URIValue struct { - path, rawPath, buffer *[]byte - - key string -} - -func newURIValue(path *[]byte, rawPath *[]byte, buffer *[]byte, key string) URIValue { - return URIValue{path: path, rawPath: rawPath, buffer: buffer, key: key} -} - -func (u URIValue) modifyURI(value string) (err error) { - *u.path, *u.buffer, err = replacePathElement(*u.path, *u.buffer, u.key, value, false) - if err != nil { - return err - } - *u.rawPath, *u.buffer, err = replacePathElement(*u.rawPath, *u.buffer, u.key, value, true) - return err -} - -// Boolean encodes v as a URI string value -func (u URIValue) Boolean(v bool) error { - return u.modifyURI(strconv.FormatBool(v)) -} - -// String encodes v as a URI string value -func (u URIValue) String(v string) error { - return u.modifyURI(v) -} - -// Byte encodes v as a URI string value -func (u URIValue) Byte(v int8) error { - return u.Long(int64(v)) -} - -// Short encodes v as a URI string value -func (u URIValue) Short(v int16) error { - return u.Long(int64(v)) -} - -// Integer encodes v as a URI string value -func (u URIValue) Integer(v int32) error { - return u.Long(int64(v)) -} - -// Long encodes v as a URI string value -func (u URIValue) Long(v int64) error { - return u.modifyURI(strconv.FormatInt(v, 10)) -} - -// Float encodes v as a query string value -func (u URIValue) Float(v float32) error { - return u.float(float64(v), 32) -} - -// Double encodes v as a query string value -func (u URIValue) Double(v float64) error { - return u.float(v, 64) -} - -func (u URIValue) float(v float64, bitSize int) error { - switch { - case math.IsNaN(v): - return u.String(floatNaN) - case math.IsInf(v, 1): - return u.String(floatInfinity) - case math.IsInf(v, -1): - return u.String(floatNegInfinity) - default: - return u.modifyURI(strconv.FormatFloat(v, 'f', -1, bitSize)) - } -} - -// BigInteger encodes v as a query string value -func (u URIValue) BigInteger(v *big.Int) error { - return u.modifyURI(v.String()) -} - -// BigDecimal encodes v as a query string value -func (u URIValue) BigDecimal(v *big.Float) error { - if i, accuracy := v.Int64(); accuracy == big.Exact { - return u.Long(i) - } - return u.modifyURI(v.Text('e', -1)) -} - -// SplitURI parses a Smithy HTTP binding trait URI -func SplitURI(uri string) (path, query string) { - queryStart := strings.IndexRune(uri, '?') - if queryStart == -1 { - path = uri - return path, query - } - - path = uri[:queryStart] - if queryStart+1 >= len(uri) { - return path, query - } - query = uri[queryStart+1:] - - return path, query -} diff --git a/vendor/github.com/aws/smithy-go/encoding/json/array.go b/vendor/github.com/aws/smithy-go/encoding/json/array.go deleted file mode 100644 index 7a232f6..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/json/array.go +++ /dev/null @@ -1,35 +0,0 @@ -package json - -import ( - "bytes" -) - -// Array represents the encoding of a JSON Array -type Array struct { - w *bytes.Buffer - writeComma bool - scratch *[]byte -} - -func newArray(w *bytes.Buffer, scratch *[]byte) *Array { - w.WriteRune(leftBracket) - return &Array{w: w, scratch: scratch} -} - -// Value adds a new element to the JSON Array. -// Returns a Value type that is used to encode -// the array element. -func (a *Array) Value() Value { - if a.writeComma { - a.w.WriteRune(comma) - } else { - a.writeComma = true - } - - return newValue(a.w, a.scratch) -} - -// Close encodes the end of the JSON Array -func (a *Array) Close() { - a.w.WriteRune(rightBracket) -} diff --git a/vendor/github.com/aws/smithy-go/encoding/json/constants.go b/vendor/github.com/aws/smithy-go/encoding/json/constants.go deleted file mode 100644 index 9104409..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/json/constants.go +++ /dev/null @@ -1,15 +0,0 @@ -package json - -const ( - leftBrace = '{' - rightBrace = '}' - - leftBracket = '[' - rightBracket = ']' - - comma = ',' - quote = '"' - colon = ':' - - null = "null" -) diff --git a/vendor/github.com/aws/smithy-go/encoding/json/decoder_util.go b/vendor/github.com/aws/smithy-go/encoding/json/decoder_util.go deleted file mode 100644 index 7050c85..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/json/decoder_util.go +++ /dev/null @@ -1,139 +0,0 @@ -package json - -import ( - "bytes" - "encoding/json" - "fmt" - "io" -) - -// DiscardUnknownField discards unknown fields from a decoder body. -// This function is useful while deserializing a JSON body with additional -// unknown information that should be discarded. -func DiscardUnknownField(decoder *json.Decoder) error { - // This deliberately does not share logic with CollectUnknownField, even - // though it could, because if we were to delegate to that then we'd incur - // extra allocations and general memory usage. - v, err := decoder.Token() - if err == io.EOF { - return nil - } - if err != nil { - return err - } - - if _, ok := v.(json.Delim); ok { - for decoder.More() { - err = DiscardUnknownField(decoder) - } - endToken, err := decoder.Token() - if err != nil { - return err - } - if _, ok := endToken.(json.Delim); !ok { - return fmt.Errorf("invalid JSON : expected json delimiter, found %T %v", - endToken, endToken) - } - } - - return nil -} - -// CollectUnknownField grabs the contents of unknown fields from the decoder body -// and returns them as a byte slice. This is useful for skipping unknown fields without -// completely discarding them. -func CollectUnknownField(decoder *json.Decoder) ([]byte, error) { - result, err := collectUnknownField(decoder) - if err != nil { - return nil, err - } - - buff := bytes.NewBuffer(nil) - encoder := json.NewEncoder(buff) - - if err := encoder.Encode(result); err != nil { - return nil, err - } - - return buff.Bytes(), nil -} - -func collectUnknownField(decoder *json.Decoder) (interface{}, error) { - // Grab the initial value. This could either be a concrete value like a string or a a - // delimiter. - token, err := decoder.Token() - if err == io.EOF { - return nil, nil - } - if err != nil { - return nil, err - } - - // If it's an array or object, we'll need to recurse. - delim, ok := token.(json.Delim) - if ok { - var result interface{} - if delim == '{' { - result, err = collectUnknownObject(decoder) - if err != nil { - return nil, err - } - } else { - result, err = collectUnknownArray(decoder) - if err != nil { - return nil, err - } - } - - // Discard the closing token. decoder.Token handles checking for matching delimiters - if _, err := decoder.Token(); err != nil { - return nil, err - } - return result, nil - } - - return token, nil -} - -func collectUnknownArray(decoder *json.Decoder) ([]interface{}, error) { - // We need to create an empty array here instead of a nil array, since by getting - // into this function at all we necessarily have seen a non-nil list. - array := []interface{}{} - - for decoder.More() { - value, err := collectUnknownField(decoder) - if err != nil { - return nil, err - } - array = append(array, value) - } - - return array, nil -} - -func collectUnknownObject(decoder *json.Decoder) (map[string]interface{}, error) { - object := make(map[string]interface{}) - - for decoder.More() { - key, err := collectUnknownField(decoder) - if err != nil { - return nil, err - } - - // Keys have to be strings, which is particularly important as the encoder - // won't except a map with interface{} keys - stringKey, ok := key.(string) - if !ok { - return nil, fmt.Errorf("expected string key, found %T", key) - } - - value, err := collectUnknownField(decoder) - if err != nil { - return nil, err - } - - object[stringKey] = value - } - - return object, nil -} diff --git a/vendor/github.com/aws/smithy-go/encoding/json/encoder.go b/vendor/github.com/aws/smithy-go/encoding/json/encoder.go deleted file mode 100644 index 8772953..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/json/encoder.go +++ /dev/null @@ -1,30 +0,0 @@ -package json - -import ( - "bytes" -) - -// Encoder is JSON encoder that supports construction of JSON values -// using methods. -type Encoder struct { - w *bytes.Buffer - Value -} - -// NewEncoder returns a new JSON encoder -func NewEncoder() *Encoder { - writer := bytes.NewBuffer(nil) - scratch := make([]byte, 64) - - return &Encoder{w: writer, Value: newValue(writer, &scratch)} -} - -// String returns the String output of the JSON encoder -func (e Encoder) String() string { - return e.w.String() -} - -// Bytes returns the []byte slice of the JSON encoder -func (e Encoder) Bytes() []byte { - return e.w.Bytes() -} diff --git a/vendor/github.com/aws/smithy-go/encoding/json/escape.go b/vendor/github.com/aws/smithy-go/encoding/json/escape.go deleted file mode 100644 index d984d0c..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/json/escape.go +++ /dev/null @@ -1,198 +0,0 @@ -// 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. - -// Copied and modified from Go 1.8 stdlib's encoding/json/#safeSet - -package json - -import ( - "bytes" - "unicode/utf8" -) - -// safeSet holds the value true if the ASCII character with the given array -// position can be represented inside a JSON string without any further -// escaping. -// -// All values are true except for the ASCII control characters (0-31), the -// double quote ("), and the backslash character ("\"). -var safeSet = [utf8.RuneSelf]bool{ - ' ': true, - '!': true, - '"': false, - '#': true, - '$': true, - '%': true, - '&': true, - '\'': true, - '(': true, - ')': true, - '*': true, - '+': true, - ',': true, - '-': true, - '.': true, - '/': true, - '0': true, - '1': true, - '2': true, - '3': true, - '4': true, - '5': true, - '6': true, - '7': true, - '8': true, - '9': true, - ':': true, - ';': true, - '<': true, - '=': true, - '>': true, - '?': true, - '@': true, - 'A': true, - 'B': true, - 'C': true, - 'D': true, - 'E': true, - 'F': true, - 'G': true, - 'H': true, - 'I': true, - 'J': true, - 'K': true, - 'L': true, - 'M': true, - 'N': true, - 'O': true, - 'P': true, - 'Q': true, - 'R': true, - 'S': true, - 'T': true, - 'U': true, - 'V': true, - 'W': true, - 'X': true, - 'Y': true, - 'Z': true, - '[': true, - '\\': false, - ']': true, - '^': true, - '_': true, - '`': true, - 'a': true, - 'b': true, - 'c': true, - 'd': true, - 'e': true, - 'f': true, - 'g': true, - 'h': true, - 'i': true, - 'j': true, - 'k': true, - 'l': true, - 'm': true, - 'n': true, - 'o': true, - 'p': true, - 'q': true, - 'r': true, - 's': true, - 't': true, - 'u': true, - 'v': true, - 'w': true, - 'x': true, - 'y': true, - 'z': true, - '{': true, - '|': true, - '}': true, - '~': true, - '\u007f': true, -} - -// copied from Go 1.8 stdlib's encoding/json/#hex -var hex = "0123456789abcdef" - -// escapeStringBytes escapes and writes the passed in string bytes to the dst -// buffer -// -// Copied and modifed from Go 1.8 stdlib's encodeing/json/#encodeState.stringBytes -func escapeStringBytes(e *bytes.Buffer, s []byte) { - e.WriteByte('"') - start := 0 - for i := 0; i < len(s); { - if b := s[i]; b < utf8.RuneSelf { - if safeSet[b] { - i++ - continue - } - if start < i { - e.Write(s[start:i]) - } - switch b { - case '\\', '"': - e.WriteByte('\\') - e.WriteByte(b) - case '\n': - e.WriteByte('\\') - e.WriteByte('n') - case '\r': - e.WriteByte('\\') - e.WriteByte('r') - case '\t': - e.WriteByte('\\') - e.WriteByte('t') - default: - // This encodes bytes < 0x20 except for \t, \n and \r. - // If escapeHTML is set, it also escapes <, >, and & - // because they can lead to security holes when - // user-controlled strings are rendered into JSON - // and served to some browsers. - e.WriteString(`\u00`) - e.WriteByte(hex[b>>4]) - e.WriteByte(hex[b&0xF]) - } - i++ - start = i - continue - } - c, size := utf8.DecodeRune(s[i:]) - if c == utf8.RuneError && size == 1 { - if start < i { - e.Write(s[start:i]) - } - e.WriteString(`\ufffd`) - i += size - start = i - continue - } - // U+2028 is LINE SEPARATOR. - // U+2029 is PARAGRAPH SEPARATOR. - // They are both technically valid characters in JSON strings, - // but don't work in JSONP, which has to be evaluated as JavaScript, - // and can lead to security holes there. It is valid JSON to - // escape them, so we do so unconditionally. - // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. - if c == '\u2028' || c == '\u2029' { - if start < i { - e.Write(s[start:i]) - } - e.WriteString(`\u202`) - e.WriteByte(hex[c&0xF]) - i += size - start = i - continue - } - i += size - } - if start < len(s) { - e.Write(s[start:]) - } - e.WriteByte('"') -} diff --git a/vendor/github.com/aws/smithy-go/encoding/json/object.go b/vendor/github.com/aws/smithy-go/encoding/json/object.go deleted file mode 100644 index 722346d..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/json/object.go +++ /dev/null @@ -1,40 +0,0 @@ -package json - -import ( - "bytes" -) - -// Object represents the encoding of a JSON Object type -type Object struct { - w *bytes.Buffer - writeComma bool - scratch *[]byte -} - -func newObject(w *bytes.Buffer, scratch *[]byte) *Object { - w.WriteRune(leftBrace) - return &Object{w: w, scratch: scratch} -} - -func (o *Object) writeKey(key string) { - escapeStringBytes(o.w, []byte(key)) - o.w.WriteRune(colon) -} - -// Key adds the given named key to the JSON object. -// Returns a Value encoder that should be used to encode -// a JSON value type. -func (o *Object) Key(name string) Value { - if o.writeComma { - o.w.WriteRune(comma) - } else { - o.writeComma = true - } - o.writeKey(name) - return newValue(o.w, o.scratch) -} - -// Close encodes the end of the JSON Object -func (o *Object) Close() { - o.w.WriteRune(rightBrace) -} diff --git a/vendor/github.com/aws/smithy-go/encoding/json/value.go b/vendor/github.com/aws/smithy-go/encoding/json/value.go deleted file mode 100644 index b41ff1e..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/json/value.go +++ /dev/null @@ -1,149 +0,0 @@ -package json - -import ( - "bytes" - "encoding/base64" - "math/big" - "strconv" - - "github.com/aws/smithy-go/encoding" -) - -// Value represents a JSON Value type -// JSON Value types: Object, Array, String, Number, Boolean, and Null -type Value struct { - w *bytes.Buffer - scratch *[]byte -} - -// newValue returns a new Value encoder -func newValue(w *bytes.Buffer, scratch *[]byte) Value { - return Value{w: w, scratch: scratch} -} - -// String encodes v as a JSON string -func (jv Value) String(v string) { - escapeStringBytes(jv.w, []byte(v)) -} - -// Byte encodes v as a JSON number -func (jv Value) Byte(v int8) { - jv.Long(int64(v)) -} - -// Short encodes v as a JSON number -func (jv Value) Short(v int16) { - jv.Long(int64(v)) -} - -// Integer encodes v as a JSON number -func (jv Value) Integer(v int32) { - jv.Long(int64(v)) -} - -// Long encodes v as a JSON number -func (jv Value) Long(v int64) { - *jv.scratch = strconv.AppendInt((*jv.scratch)[:0], v, 10) - jv.w.Write(*jv.scratch) -} - -// ULong encodes v as a JSON number -func (jv Value) ULong(v uint64) { - *jv.scratch = strconv.AppendUint((*jv.scratch)[:0], v, 10) - jv.w.Write(*jv.scratch) -} - -// Float encodes v as a JSON number -func (jv Value) Float(v float32) { - jv.float(float64(v), 32) -} - -// Double encodes v as a JSON number -func (jv Value) Double(v float64) { - jv.float(v, 64) -} - -func (jv Value) float(v float64, bits int) { - *jv.scratch = encoding.EncodeFloat((*jv.scratch)[:0], v, bits) - jv.w.Write(*jv.scratch) -} - -// Boolean encodes v as a JSON boolean -func (jv Value) Boolean(v bool) { - *jv.scratch = strconv.AppendBool((*jv.scratch)[:0], v) - jv.w.Write(*jv.scratch) -} - -// Base64EncodeBytes writes v as a base64 value in JSON string -func (jv Value) Base64EncodeBytes(v []byte) { - encodeByteSlice(jv.w, (*jv.scratch)[:0], v) -} - -// Write writes v directly to the JSON document -func (jv Value) Write(v []byte) { - jv.w.Write(v) -} - -// Array returns a new Array encoder -func (jv Value) Array() *Array { - return newArray(jv.w, jv.scratch) -} - -// Object returns a new Object encoder -func (jv Value) Object() *Object { - return newObject(jv.w, jv.scratch) -} - -// Null encodes a null JSON value -func (jv Value) Null() { - jv.w.WriteString(null) -} - -// BigInteger encodes v as JSON value -func (jv Value) BigInteger(v *big.Int) { - jv.w.Write([]byte(v.Text(10))) -} - -// BigDecimal encodes v as JSON value -func (jv Value) BigDecimal(v *big.Float) { - if i, accuracy := v.Int64(); accuracy == big.Exact { - jv.Long(i) - return - } - // TODO: Should this try to match ES6 ToString similar to stdlib JSON? - jv.w.Write([]byte(v.Text('e', -1))) -} - -// Based on encoding/json encodeByteSlice from the Go Standard Library -// https://golang.org/src/encoding/json/encode.go -func encodeByteSlice(w *bytes.Buffer, scratch []byte, v []byte) { - if v == nil { - w.WriteString(null) - return - } - - w.WriteRune(quote) - - encodedLen := base64.StdEncoding.EncodedLen(len(v)) - if encodedLen <= len(scratch) { - // If the encoded bytes fit in e.scratch, avoid an extra - // allocation and use the cheaper Encoding.Encode. - dst := scratch[:encodedLen] - base64.StdEncoding.Encode(dst, v) - w.Write(dst) - } else if encodedLen <= 1024 { - // The encoded bytes are short enough to allocate for, and - // Encoding.Encode is still cheaper. - dst := make([]byte, encodedLen) - base64.StdEncoding.Encode(dst, v) - w.Write(dst) - } else { - // The encoded bytes are too long to cheaply allocate, and - // Encoding.Encode is no longer noticeably cheaper. - enc := base64.NewEncoder(base64.StdEncoding, w) - enc.Write(v) - enc.Close() - } - - w.WriteRune(quote) -} diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/array.go b/vendor/github.com/aws/smithy-go/encoding/xml/array.go deleted file mode 100644 index 508f3c9..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/array.go +++ /dev/null @@ -1,49 +0,0 @@ -package xml - -// arrayMemberWrapper is the default member wrapper tag name for XML Array type -var arrayMemberWrapper = StartElement{ - Name: Name{Local: "member"}, -} - -// Array represents the encoding of a XML array type -type Array struct { - w writer - scratch *[]byte - - // member start element is the array member wrapper start element - memberStartElement StartElement - - // isFlattened indicates if the array is a flattened array. - isFlattened bool -} - -// newArray returns an array encoder. -// It also takes in the member start element, array start element. -// It takes in a isFlattened bool, indicating that an array is flattened array. -// -// A wrapped array ["value1", "value2"] is represented as -// `value1value2`. - -// A flattened array `someList: ["value1", "value2"]` is represented as -// `value1value2`. -func newArray(w writer, scratch *[]byte, memberStartElement StartElement, arrayStartElement StartElement, isFlattened bool) *Array { - var memberWrapper = memberStartElement - if isFlattened { - memberWrapper = arrayStartElement - } - - return &Array{ - w: w, - scratch: scratch, - memberStartElement: memberWrapper, - isFlattened: isFlattened, - } -} - -// Member adds a new member to the XML array. -// It returns a Value encoder. -func (a *Array) Member() Value { - v := newValue(a.w, a.scratch, a.memberStartElement) - v.isFlattened = a.isFlattened - return v -} diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/constants.go b/vendor/github.com/aws/smithy-go/encoding/xml/constants.go deleted file mode 100644 index ccee90a..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/constants.go +++ /dev/null @@ -1,10 +0,0 @@ -package xml - -const ( - leftAngleBracket = '<' - rightAngleBracket = '>' - forwardSlash = '/' - colon = ':' - equals = '=' - quote = '"' -) diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/doc.go b/vendor/github.com/aws/smithy-go/encoding/xml/doc.go deleted file mode 100644 index f920009..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/doc.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Package xml holds the XMl encoder utility. This utility is written in accordance to our design to delegate to -shape serializer function in which a xml.Value will be passed around. - -Resources followed: https://smithy.io/2.0/spec/protocol-traits.html#xml-bindings - -Member Element - -Member element should be used to encode xml shapes into xml elements except for flattened xml shapes. Member element -write their own element start tag. These elements should always be closed. - -Flattened Element - -Flattened element should be used to encode shapes marked with flattened trait into xml elements. Flattened element -do not write a start tag, and thus should not be closed. - -Simple types encoding - -All simple type methods on value such as String(), Long() etc; auto close the associated member element. - -Array - -Array returns the collection encoder. It has two modes, wrapped and flattened encoding. - -Wrapped arrays have two methods Array() and ArrayWithCustomName() which facilitate array member wrapping. -By default, a wrapped array members are wrapped with `member` named start element. - - appletree - -Flattened arrays rely on Value being marked as flattened. -If a shape is marked as flattened, Array() will use the shape element name as wrapper for array elements. - - appletree - -Map - -Map is the map encoder. It has two modes, wrapped and flattened encoding. - -Wrapped map has Array() method, which facilitate map member wrapping. -By default, a wrapped map members are wrapped with `entry` named start element. - - appletreesnowice - -Flattened map rely on Value being marked as flattened. -If a shape is marked as flattened, Map() will use the shape element name as wrapper for map entry elements. - - appletreesnowice -*/ -package xml diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/element.go b/vendor/github.com/aws/smithy-go/encoding/xml/element.go deleted file mode 100644 index ae84e79..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/element.go +++ /dev/null @@ -1,91 +0,0 @@ -// 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. - -// Copied and modified from Go 1.14 stdlib's encoding/xml - -package xml - -// A Name represents an XML name (Local) annotated -// with a name space identifier (Space). -// In tokens returned by Decoder.Token, the Space identifier -// is given as a canonical URL, not the short prefix used -// in the document being parsed. -type Name struct { - Space, Local string -} - -// An Attr represents an attribute in an XML element (Name=Value). -type Attr struct { - Name Name - Value string -} - -/* -NewAttribute returns a pointer to an attribute. -It takes in a local name aka attribute name, and value -representing the attribute value. -*/ -func NewAttribute(local, value string) Attr { - return Attr{ - Name: Name{ - Local: local, - }, - Value: value, - } -} - -/* -NewNamespaceAttribute returns a pointer to an attribute. -It takes in a local name aka attribute name, and value -representing the attribute value. - -NewNamespaceAttribute appends `xmlns:` in front of namespace -prefix. - -For creating a name space attribute representing -`xmlns:prefix="http://example.com`, the breakdown would be: -local = "prefix" -value = "http://example.com" -*/ -func NewNamespaceAttribute(local, value string) Attr { - attr := NewAttribute(local, value) - - // default name space identifier - attr.Name.Space = "xmlns" - return attr -} - -// A StartElement represents an XML start element. -type StartElement struct { - Name Name - Attr []Attr -} - -// Copy creates a new copy of StartElement. -func (e StartElement) Copy() StartElement { - attrs := make([]Attr, len(e.Attr)) - copy(attrs, e.Attr) - e.Attr = attrs - return e -} - -// End returns the corresponding XML end element. -func (e StartElement) End() EndElement { - return EndElement{e.Name} -} - -// returns true if start element local name is empty -func (e StartElement) isZero() bool { - return len(e.Name.Local) == 0 -} - -// An EndElement represents an XML end element. -type EndElement struct { - Name Name -} - -// returns true if end element local name is empty -func (e EndElement) isZero() bool { - return len(e.Name.Local) == 0 -} diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/encoder.go b/vendor/github.com/aws/smithy-go/encoding/xml/encoder.go deleted file mode 100644 index 16fb3dd..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/encoder.go +++ /dev/null @@ -1,51 +0,0 @@ -package xml - -// writer interface used by the xml encoder to write an encoded xml -// document in a writer. -type writer interface { - - // Write takes in a byte slice and returns number of bytes written and error - Write(p []byte) (n int, err error) - - // WriteRune takes in a rune and returns number of bytes written and error - WriteRune(r rune) (n int, err error) - - // WriteString takes in a string and returns number of bytes written and error - WriteString(s string) (n int, err error) - - // String method returns a string - String() string - - // Bytes return a byte slice. - Bytes() []byte -} - -// Encoder is an XML encoder that supports construction of XML values -// using methods. The encoder takes in a writer and maintains a scratch buffer. -type Encoder struct { - w writer - scratch *[]byte -} - -// NewEncoder returns an XML encoder -func NewEncoder(w writer) *Encoder { - scratch := make([]byte, 64) - - return &Encoder{w: w, scratch: &scratch} -} - -// String returns the string output of the XML encoder -func (e Encoder) String() string { - return e.w.String() -} - -// Bytes returns the []byte slice of the XML encoder -func (e Encoder) Bytes() []byte { - return e.w.Bytes() -} - -// RootElement builds a root element encoding -// It writes it's start element tag. The value should be closed. -func (e Encoder) RootElement(element StartElement) Value { - return newValue(e.w, e.scratch, element) -} diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/error_utils.go b/vendor/github.com/aws/smithy-go/encoding/xml/error_utils.go deleted file mode 100644 index f3db6cc..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/error_utils.go +++ /dev/null @@ -1,51 +0,0 @@ -package xml - -import ( - "encoding/xml" - "fmt" - "io" -) - -// ErrorComponents represents the error response fields -// that will be deserialized from an xml error response body -type ErrorComponents struct { - Code string - Message string -} - -// GetErrorResponseComponents returns the error fields from an xml error response body -func GetErrorResponseComponents(r io.Reader, noErrorWrapping bool) (ErrorComponents, error) { - if noErrorWrapping { - var errResponse noWrappedErrorResponse - if err := xml.NewDecoder(r).Decode(&errResponse); err != nil && err != io.EOF { - return ErrorComponents{}, fmt.Errorf("error while deserializing xml error response: %w", err) - } - return ErrorComponents{ - Code: errResponse.Code, - Message: errResponse.Message, - }, nil - } - - var errResponse wrappedErrorResponse - if err := xml.NewDecoder(r).Decode(&errResponse); err != nil && err != io.EOF { - return ErrorComponents{}, fmt.Errorf("error while deserializing xml error response: %w", err) - } - return ErrorComponents{ - Code: errResponse.Code, - Message: errResponse.Message, - }, nil -} - -// noWrappedErrorResponse represents the error response body with -// no internal ... -type wrappedErrorResponse struct { - Code string `xml:"Error>Code"` - Message string `xml:"Error>Message"` -} diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/escape.go b/vendor/github.com/aws/smithy-go/encoding/xml/escape.go deleted file mode 100644 index 1c5479a..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/escape.go +++ /dev/null @@ -1,137 +0,0 @@ -// 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. - -// Copied and modified from Go 1.14 stdlib's encoding/xml - -package xml - -import ( - "unicode/utf8" -) - -// Copied from Go 1.14 stdlib's encoding/xml -var ( - escQuot = []byte(""") // shorter than """ - escApos = []byte("'") // shorter than "'" - escAmp = []byte("&") - escLT = []byte("<") - escGT = []byte(">") - escTab = []byte(" ") - escNL = []byte(" ") - escCR = []byte(" ") - escFFFD = []byte("\uFFFD") // Unicode replacement character - - // Additional Escapes - escNextLine = []byte("…") - escLS = []byte("
") -) - -// Decide whether the given rune is in the XML Character Range, per -// the Char production of https://www.xml.com/axml/testaxml.htm, -// Section 2.2 Characters. -func isInCharacterRange(r rune) (inrange bool) { - return r == 0x09 || - r == 0x0A || - r == 0x0D || - r >= 0x20 && r <= 0xD7FF || - r >= 0xE000 && r <= 0xFFFD || - r >= 0x10000 && r <= 0x10FFFF -} - -// TODO: When do we need to escape the string? -// Based on encoding/xml escapeString from the Go Standard Library. -// https://golang.org/src/encoding/xml/xml.go -func escapeString(e writer, s string) { - var esc []byte - last := 0 - for i := 0; i < len(s); { - r, width := utf8.DecodeRuneInString(s[i:]) - i += width - switch r { - case '"': - esc = escQuot - case '\'': - esc = escApos - case '&': - esc = escAmp - case '<': - esc = escLT - case '>': - esc = escGT - case '\t': - esc = escTab - case '\n': - esc = escNL - case '\r': - esc = escCR - case '\u0085': - // Not escaped by stdlib - esc = escNextLine - case '\u2028': - // Not escaped by stdlib - esc = escLS - default: - if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) { - esc = escFFFD - break - } - continue - } - e.WriteString(s[last : i-width]) - e.Write(esc) - last = i - } - e.WriteString(s[last:]) -} - -// escapeText writes to w the properly escaped XML equivalent -// of the plain text data s. If escapeNewline is true, newline -// characters will be escaped. -// -// Based on encoding/xml escapeText from the Go Standard Library. -// https://golang.org/src/encoding/xml/xml.go -func escapeText(e writer, s []byte) { - var esc []byte - last := 0 - for i := 0; i < len(s); { - r, width := utf8.DecodeRune(s[i:]) - i += width - switch r { - case '"': - esc = escQuot - case '\'': - esc = escApos - case '&': - esc = escAmp - case '<': - esc = escLT - case '>': - esc = escGT - case '\t': - esc = escTab - case '\n': - // This always escapes newline, which is different than stdlib's optional - // escape of new line. - esc = escNL - case '\r': - esc = escCR - case '\u0085': - // Not escaped by stdlib - esc = escNextLine - case '\u2028': - // Not escaped by stdlib - esc = escLS - default: - if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) { - esc = escFFFD - break - } - continue - } - e.Write(s[last : i-width]) - e.Write(esc) - last = i - } - e.Write(s[last:]) -} diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/map.go b/vendor/github.com/aws/smithy-go/encoding/xml/map.go deleted file mode 100644 index e428589..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/map.go +++ /dev/null @@ -1,53 +0,0 @@ -package xml - -// mapEntryWrapper is the default member wrapper start element for XML Map entry -var mapEntryWrapper = StartElement{ - Name: Name{Local: "entry"}, -} - -// Map represents the encoding of a XML map type -type Map struct { - w writer - scratch *[]byte - - // member start element is the map entry wrapper start element - memberStartElement StartElement - - // isFlattened returns true if the map is a flattened map - isFlattened bool -} - -// newMap returns a map encoder which sets the default map -// entry wrapper to `entry`. -// -// A map `someMap : {{key:"abc", value:"123"}}` is represented as -// `abc123`. -func newMap(w writer, scratch *[]byte) *Map { - return &Map{ - w: w, - scratch: scratch, - memberStartElement: mapEntryWrapper, - } -} - -// newFlattenedMap returns a map encoder which sets the map -// entry wrapper to the passed in memberWrapper`. -// -// A flattened map `someMap : {{key:"abc", value:"123"}}` is represented as -// `abc123`. -func newFlattenedMap(w writer, scratch *[]byte, memberWrapper StartElement) *Map { - return &Map{ - w: w, - scratch: scratch, - memberStartElement: memberWrapper, - isFlattened: true, - } -} - -// Entry returns a Value encoder with map's element. -// It writes the member wrapper start tag for each entry. -func (m *Map) Entry() Value { - v := newValue(m.w, m.scratch, m.memberStartElement) - v.isFlattened = m.isFlattened - return v -} diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/value.go b/vendor/github.com/aws/smithy-go/encoding/xml/value.go deleted file mode 100644 index 09434b2..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/value.go +++ /dev/null @@ -1,302 +0,0 @@ -package xml - -import ( - "encoding/base64" - "fmt" - "math/big" - "strconv" - - "github.com/aws/smithy-go/encoding" -) - -// Value represents an XML Value type -// XML Value types: Object, Array, Map, String, Number, Boolean. -type Value struct { - w writer - scratch *[]byte - - // xml start element is the associated start element for the Value - startElement StartElement - - // indicates if the Value represents a flattened shape - isFlattened bool -} - -// newFlattenedValue returns a Value encoder. newFlattenedValue does NOT write the start element tag -func newFlattenedValue(w writer, scratch *[]byte, startElement StartElement) Value { - return Value{ - w: w, - scratch: scratch, - startElement: startElement, - } -} - -// newValue writes the start element xml tag and returns a Value -func newValue(w writer, scratch *[]byte, startElement StartElement) Value { - writeStartElement(w, startElement) - return Value{w: w, scratch: scratch, startElement: startElement} -} - -// writeStartElement takes in a start element and writes it. -// It handles namespace, attributes in start element. -func writeStartElement(w writer, el StartElement) error { - if el.isZero() { - return fmt.Errorf("xml start element cannot be nil") - } - - w.WriteRune(leftAngleBracket) - - if len(el.Name.Space) != 0 { - escapeString(w, el.Name.Space) - w.WriteRune(colon) - } - escapeString(w, el.Name.Local) - for _, attr := range el.Attr { - w.WriteRune(' ') - writeAttribute(w, &attr) - } - - w.WriteRune(rightAngleBracket) - return nil -} - -// writeAttribute writes an attribute from a provided Attribute -// For a namespace attribute, the attr.Name.Space must be defined as "xmlns". -// https://www.w3.org/TR/REC-xml-names/#NT-DefaultAttName -func writeAttribute(w writer, attr *Attr) { - // if local, space both are not empty - if len(attr.Name.Space) != 0 && len(attr.Name.Local) != 0 { - escapeString(w, attr.Name.Space) - w.WriteRune(colon) - } - - // if prefix is empty, the default `xmlns` space should be used as prefix. - if len(attr.Name.Local) == 0 { - attr.Name.Local = attr.Name.Space - } - - escapeString(w, attr.Name.Local) - w.WriteRune(equals) - w.WriteRune(quote) - escapeString(w, attr.Value) - w.WriteRune(quote) -} - -// writeEndElement takes in a end element and writes it. -func writeEndElement(w writer, el EndElement) error { - if el.isZero() { - return fmt.Errorf("xml end element cannot be nil") - } - - w.WriteRune(leftAngleBracket) - w.WriteRune(forwardSlash) - - if len(el.Name.Space) != 0 { - escapeString(w, el.Name.Space) - w.WriteRune(colon) - } - escapeString(w, el.Name.Local) - w.WriteRune(rightAngleBracket) - - return nil -} - -// String encodes v as a XML string. -// It will auto close the parent xml element tag. -func (xv Value) String(v string) { - escapeString(xv.w, v) - xv.Close() -} - -// Byte encodes v as a XML number. -// It will auto close the parent xml element tag. -func (xv Value) Byte(v int8) { - xv.Long(int64(v)) -} - -// Short encodes v as a XML number. -// It will auto close the parent xml element tag. -func (xv Value) Short(v int16) { - xv.Long(int64(v)) -} - -// Integer encodes v as a XML number. -// It will auto close the parent xml element tag. -func (xv Value) Integer(v int32) { - xv.Long(int64(v)) -} - -// Long encodes v as a XML number. -// It will auto close the parent xml element tag. -func (xv Value) Long(v int64) { - *xv.scratch = strconv.AppendInt((*xv.scratch)[:0], v, 10) - xv.w.Write(*xv.scratch) - - xv.Close() -} - -// Float encodes v as a XML number. -// It will auto close the parent xml element tag. -func (xv Value) Float(v float32) { - xv.float(float64(v), 32) - xv.Close() -} - -// Double encodes v as a XML number. -// It will auto close the parent xml element tag. -func (xv Value) Double(v float64) { - xv.float(v, 64) - xv.Close() -} - -func (xv Value) float(v float64, bits int) { - *xv.scratch = encoding.EncodeFloat((*xv.scratch)[:0], v, bits) - xv.w.Write(*xv.scratch) -} - -// Boolean encodes v as a XML boolean. -// It will auto close the parent xml element tag. -func (xv Value) Boolean(v bool) { - *xv.scratch = strconv.AppendBool((*xv.scratch)[:0], v) - xv.w.Write(*xv.scratch) - - xv.Close() -} - -// Base64EncodeBytes writes v as a base64 value in XML string. -// It will auto close the parent xml element tag. -func (xv Value) Base64EncodeBytes(v []byte) { - encodeByteSlice(xv.w, (*xv.scratch)[:0], v) - xv.Close() -} - -// BigInteger encodes v big.Int as XML value. -// It will auto close the parent xml element tag. -func (xv Value) BigInteger(v *big.Int) { - xv.w.Write([]byte(v.Text(10))) - xv.Close() -} - -// BigDecimal encodes v big.Float as XML value. -// It will auto close the parent xml element tag. -func (xv Value) BigDecimal(v *big.Float) { - if i, accuracy := v.Int64(); accuracy == big.Exact { - xv.Long(i) - return - } - - xv.w.Write([]byte(v.Text('e', -1))) - xv.Close() -} - -// Write writes v directly to the xml document -// if escapeXMLText is set to true, write will escape text. -// It will auto close the parent xml element tag. -func (xv Value) Write(v []byte, escapeXMLText bool) { - // escape and write xml text - if escapeXMLText { - escapeText(xv.w, v) - } else { - // write xml directly - xv.w.Write(v) - } - - xv.Close() -} - -// MemberElement does member element encoding. It returns a Value. -// Member Element method should be used for all shapes except flattened shapes. -// -// A call to MemberElement will write nested element tags directly using the -// provided start element. The value returned by MemberElement should be closed. -func (xv Value) MemberElement(element StartElement) Value { - return newValue(xv.w, xv.scratch, element) -} - -// FlattenedElement returns flattened element encoding. It returns a Value. -// This method should be used for flattened shapes. -// -// Unlike MemberElement, flattened element will NOT write element tags -// directly for the associated start element. -// -// The value returned by the FlattenedElement does not need to be closed. -func (xv Value) FlattenedElement(element StartElement) Value { - v := newFlattenedValue(xv.w, xv.scratch, element) - v.isFlattened = true - return v -} - -// Array returns an array encoder. By default, the members of array are -// wrapped with `` element tag. -// If value is marked as flattened, the start element is used to wrap the members instead of -// the `` element. -func (xv Value) Array() *Array { - return newArray(xv.w, xv.scratch, arrayMemberWrapper, xv.startElement, xv.isFlattened) -} - -/* -ArrayWithCustomName returns an array encoder. - -It takes named start element as an argument, the named start element will used to wrap xml array entries. -for eg, `entry1` -Here `customName` named start element will be wrapped on each array member. -*/ -func (xv Value) ArrayWithCustomName(element StartElement) *Array { - return newArray(xv.w, xv.scratch, element, xv.startElement, xv.isFlattened) -} - -/* -Map returns a map encoder. By default, the map entries are -wrapped with `` element tag. - -If value is marked as flattened, the start element is used to wrap the entry instead of -the `` element. -*/ -func (xv Value) Map() *Map { - // flattened map - if xv.isFlattened { - return newFlattenedMap(xv.w, xv.scratch, xv.startElement) - } - - // un-flattened map - return newMap(xv.w, xv.scratch) -} - -// encodeByteSlice is modified copy of json encoder's encodeByteSlice. -// It is used to base64 encode a byte slice. -func encodeByteSlice(w writer, scratch []byte, v []byte) { - if v == nil { - return - } - - encodedLen := base64.StdEncoding.EncodedLen(len(v)) - if encodedLen <= len(scratch) { - // If the encoded bytes fit in e.scratch, avoid an extra - // allocation and use the cheaper Encoding.Encode. - dst := scratch[:encodedLen] - base64.StdEncoding.Encode(dst, v) - w.Write(dst) - } else if encodedLen <= 1024 { - // The encoded bytes are short enough to allocate for, and - // Encoding.Encode is still cheaper. - dst := make([]byte, encodedLen) - base64.StdEncoding.Encode(dst, v) - w.Write(dst) - } else { - // The encoded bytes are too long to cheaply allocate, and - // Encoding.Encode is no longer noticeably cheaper. - enc := base64.NewEncoder(base64.StdEncoding, w) - enc.Write(v) - enc.Close() - } -} - -// IsFlattened returns true if value is for flattened shape. -func (xv Value) IsFlattened() bool { - return xv.isFlattened -} - -// Close closes the value. -func (xv Value) Close() { - writeEndElement(xv.w, xv.startElement.End()) -} diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder.go b/vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder.go deleted file mode 100644 index dc4eebd..0000000 --- a/vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder.go +++ /dev/null @@ -1,154 +0,0 @@ -package xml - -import ( - "encoding/xml" - "fmt" - "strings" -) - -// NodeDecoder is a XML decoder wrapper that is responsible to decoding -// a single XML Node element and it's nested member elements. This wrapper decoder -// takes in the start element of the top level node being decoded. -type NodeDecoder struct { - Decoder *xml.Decoder - StartEl xml.StartElement -} - -// WrapNodeDecoder returns an initialized XMLNodeDecoder -func WrapNodeDecoder(decoder *xml.Decoder, startEl xml.StartElement) NodeDecoder { - return NodeDecoder{ - Decoder: decoder, - StartEl: startEl, - } -} - -// Token on a Node Decoder returns a xml StartElement. It returns a boolean that indicates the -// a token is the node decoder's end node token; and an error which indicates any error -// that occurred while retrieving the start element -func (d NodeDecoder) Token() (t xml.StartElement, done bool, err error) { - for { - token, e := d.Decoder.Token() - if e != nil { - return t, done, e - } - - // check if we reach end of the node being decoded - if el, ok := token.(xml.EndElement); ok { - return t, el == d.StartEl.End(), err - } - - if t, ok := token.(xml.StartElement); ok { - return restoreAttrNamespaces(t), false, err - } - - // skip token if it is a comment or preamble or empty space value due to indentation - // or if it's a value and is not expected - } -} - -// restoreAttrNamespaces update XML attributes to restore the short namespaces found within -// the raw XML document. -func restoreAttrNamespaces(node xml.StartElement) xml.StartElement { - if len(node.Attr) == 0 { - return node - } - - // Generate a mapping of XML namespace values to their short names. - ns := map[string]string{} - for _, a := range node.Attr { - if a.Name.Space == "xmlns" { - ns[a.Value] = a.Name.Local - break - } - } - - for i, a := range node.Attr { - if a.Name.Space == "xmlns" { - continue - } - // By default, xml.Decoder will fully resolve these namespaces. So if you had - // then by default the second attribute would have the `Name.Space` resolved to `baz`. But we need it to - // continue to resolve as `bar` so we can easily identify it later on. - if v, ok := ns[node.Attr[i].Name.Space]; ok { - node.Attr[i].Name.Space = v - } - } - return node -} - -// GetElement looks for the given tag name at the current level, and returns the element if found, and -// skipping over non-matching elements. Returns an error if the node is not found, or if an error occurs while walking -// the document. -func (d NodeDecoder) GetElement(name string) (t xml.StartElement, err error) { - for { - token, done, err := d.Token() - if err != nil { - return t, err - } - if done { - return t, fmt.Errorf("%s node not found", name) - } - switch { - case strings.EqualFold(name, token.Name.Local): - return token, nil - default: - err = d.Decoder.Skip() - if err != nil { - return t, err - } - } - } -} - -// Value provides an abstraction to retrieve char data value within an xml element. -// The method will return an error if it encounters a nested xml element instead of char data. -// This method should only be used to retrieve simple type or blob shape values as []byte. -func (d NodeDecoder) Value() (c []byte, err error) { - t, e := d.Decoder.Token() - if e != nil { - return c, e - } - - endElement := d.StartEl.End() - - switch ev := t.(type) { - case xml.CharData: - c = ev.Copy() - case xml.EndElement: // end tag or self-closing - if ev == endElement { - return []byte{}, err - } - return c, fmt.Errorf("expected value for %v element, got %T type %v instead", d.StartEl.Name.Local, t, t) - default: - return c, fmt.Errorf("expected value for %v element, got %T type %v instead", d.StartEl.Name.Local, t, t) - } - - t, e = d.Decoder.Token() - if e != nil { - return c, e - } - - if ev, ok := t.(xml.EndElement); ok { - if ev == endElement { - return c, err - } - } - - return c, fmt.Errorf("expected end element %v, got %T type %v instead", endElement, t, t) -} - -// FetchRootElement takes in a decoder and returns the first start element within the xml body. -// This function is useful in fetching the start element of an XML response and ignore the -// comments and preamble -func FetchRootElement(decoder *xml.Decoder) (startElement xml.StartElement, err error) { - for { - t, e := decoder.Token() - if e != nil { - return startElement, e - } - - if startElement, ok := t.(xml.StartElement); ok { - return startElement, err - } - } -} diff --git a/vendor/github.com/aws/smithy-go/endpoints/endpoint.go b/vendor/github.com/aws/smithy-go/endpoints/endpoint.go deleted file mode 100644 index f778272..0000000 --- a/vendor/github.com/aws/smithy-go/endpoints/endpoint.go +++ /dev/null @@ -1,23 +0,0 @@ -package transport - -import ( - "net/http" - "net/url" - - "github.com/aws/smithy-go" -) - -// Endpoint is the endpoint object returned by Endpoint resolution V2 -type Endpoint struct { - // The complete URL minimally specifying the scheme and host. - // May optionally specify the port and base path component. - URI url.URL - - // An optional set of headers to be sent using transport layer headers. - Headers http.Header - - // A grab-bag property map of endpoint attributes. The - // values present here are subject to change, or being add/removed at any - // time. - Properties smithy.Properties -} diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go deleted file mode 100644 index e24e190..0000000 --- a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package rulesfn provides endpoint rule functions for evaluating endpoint -// resolution rules. - -package rulesfn diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go deleted file mode 100644 index 5cf4a7b..0000000 --- a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go +++ /dev/null @@ -1,25 +0,0 @@ -package rulesfn - -// Substring returns the substring of the input provided. If the start or stop -// indexes are not valid for the input nil will be returned. If errors occur -// they will be added to the provided [ErrorCollector]. -func SubString(input string, start, stop int, reverse bool) *string { - if start < 0 || stop < 1 || start >= stop || len(input) < stop { - return nil - } - - for _, r := range input { - if r > 127 { - return nil - } - } - - if !reverse { - v := input[start:stop] - return &v - } - - rStart := len(input) - stop - rStop := len(input) - start - return SubString(input, rStart, rStop, false) -} diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go deleted file mode 100644 index 0c11541..0000000 --- a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go +++ /dev/null @@ -1,130 +0,0 @@ -package rulesfn - -import ( - "fmt" - "net" - "net/url" - "strings" - - smithyhttp "github.com/aws/smithy-go/transport/http" -) - -// IsValidHostLabel returns if the input is a single valid [RFC 1123] host -// label. If allowSubDomains is true, will allow validation to include nested -// host labels. Returns false if the input is not a valid host label. If errors -// occur they will be added to the provided [ErrorCollector]. -// -// [RFC 1123]: https://www.ietf.org/rfc/rfc1123.txt -func IsValidHostLabel(input string, allowSubDomains bool) bool { - var labels []string - if allowSubDomains { - labels = strings.Split(input, ".") - } else { - labels = []string{input} - } - - for _, label := range labels { - if !smithyhttp.ValidHostLabel(label) { - return false - } - } - - return true -} - -// ParseURL returns a [URL] if the provided string could be parsed. Returns nil -// if the string could not be parsed. Any parsing error will be added to the -// [ErrorCollector]. -// -// If the input URL string contains an IP6 address with a zone index. The -// returned [builtin.URL.Authority] value will contain the percent escaped (%) -// zone index separator. -func ParseURL(input string) *URL { - u, err := url.Parse(input) - if err != nil { - return nil - } - - if u.RawQuery != "" { - return nil - } - - if u.Scheme != "http" && u.Scheme != "https" { - return nil - } - - normalizedPath := u.Path - if !strings.HasPrefix(normalizedPath, "/") { - normalizedPath = "/" + normalizedPath - } - if !strings.HasSuffix(normalizedPath, "/") { - normalizedPath = normalizedPath + "/" - } - - // IP6 hosts may have zone indexes that need to be escaped to be valid in a - // URI. The Go URL parser will unescape the `%25` into `%`. This needs to - // be reverted since the returned URL will be used in string builders. - authority := strings.ReplaceAll(u.Host, "%", "%25") - - return &URL{ - Scheme: u.Scheme, - Authority: authority, - Path: u.Path, - NormalizedPath: normalizedPath, - IsIp: net.ParseIP(hostnameWithoutZone(u)) != nil, - } -} - -// URL provides the structure describing the parts of a parsed URL returned by -// [ParseURL]. -type URL struct { - Scheme string // https://www.rfc-editor.org/rfc/rfc3986#section-3.1 - Authority string // https://www.rfc-editor.org/rfc/rfc3986#section-3.2 - Path string // https://www.rfc-editor.org/rfc/rfc3986#section-3.3 - NormalizedPath string // https://www.rfc-editor.org/rfc/rfc3986#section-6.2.3 - IsIp bool -} - -// URIEncode returns an percent-encoded [RFC3986 section 2.1] version of the -// input string. -// -// [RFC3986 section 2.1]: https://www.rfc-editor.org/rfc/rfc3986#section-2.1 -func URIEncode(input string) string { - var output strings.Builder - for _, c := range []byte(input) { - if validPercentEncodedChar(c) { - output.WriteByte(c) - continue - } - - fmt.Fprintf(&output, "%%%X", c) - } - - return output.String() -} - -func validPercentEncodedChar(c byte) bool { - return (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || - c == '-' || c == '_' || c == '.' || c == '~' -} - -// hostname implements u.Hostname() but strips the ipv6 zone ID (if present) -// such that net.ParseIP can still recognize IPv6 addresses with zone IDs. -// -// FUTURE(10/2023): netip.ParseAddr handles this natively but we can't take -// that package as a dependency yet due to our min go version (1.15, netip -// starts in 1.18). When we align with go runtime deprecation policy in -// 10/2023, we can remove this. -func hostnameWithoutZone(u *url.URL) string { - full := u.Hostname() - - // this more or less mimics the internals of net/ (see unexported - // splitHostZone in that source) but throws the zone away because we don't - // need it - if i := strings.LastIndex(full, "%"); i > -1 { - return full[:i] - } - return full -} diff --git a/vendor/github.com/aws/smithy-go/errors.go b/vendor/github.com/aws/smithy-go/errors.go deleted file mode 100644 index d6948d0..0000000 --- a/vendor/github.com/aws/smithy-go/errors.go +++ /dev/null @@ -1,137 +0,0 @@ -package smithy - -import "fmt" - -// APIError provides the generic API and protocol agnostic error type all SDK -// generated exception types will implement. -type APIError interface { - error - - // ErrorCode returns the error code for the API exception. - ErrorCode() string - // ErrorMessage returns the error message for the API exception. - ErrorMessage() string - // ErrorFault returns the fault for the API exception. - ErrorFault() ErrorFault -} - -// GenericAPIError provides a generic concrete API error type that SDKs can use -// to deserialize error responses into. Should be used for unmodeled or untyped -// errors. -type GenericAPIError struct { - Code string - Message string - Fault ErrorFault -} - -// ErrorCode returns the error code for the API exception. -func (e *GenericAPIError) ErrorCode() string { return e.Code } - -// ErrorMessage returns the error message for the API exception. -func (e *GenericAPIError) ErrorMessage() string { return e.Message } - -// ErrorFault returns the fault for the API exception. -func (e *GenericAPIError) ErrorFault() ErrorFault { return e.Fault } - -func (e *GenericAPIError) Error() string { - return fmt.Sprintf("api error %s: %s", e.Code, e.Message) -} - -var _ APIError = (*GenericAPIError)(nil) - -// OperationError decorates an underlying error which occurred while invoking -// an operation with names of the operation and API. -type OperationError struct { - ServiceID string - OperationName string - Err error -} - -// Service returns the name of the API service the error occurred with. -func (e *OperationError) Service() string { return e.ServiceID } - -// Operation returns the name of the API operation the error occurred with. -func (e *OperationError) Operation() string { return e.OperationName } - -// Unwrap returns the nested error if any, or nil. -func (e *OperationError) Unwrap() error { return e.Err } - -func (e *OperationError) Error() string { - return fmt.Sprintf("operation error %s: %s, %v", e.ServiceID, e.OperationName, e.Err) -} - -// DeserializationError provides a wrapper for an error that occurs during -// deserialization. -type DeserializationError struct { - Err error // original error - Snapshot []byte -} - -// Error returns a formatted error for DeserializationError -func (e *DeserializationError) Error() string { - const msg = "deserialization failed" - if e.Err == nil { - return msg - } - return fmt.Sprintf("%s, %v", msg, e.Err) -} - -// Unwrap returns the underlying Error in DeserializationError -func (e *DeserializationError) Unwrap() error { return e.Err } - -// ErrorFault provides the type for a Smithy API error fault. -type ErrorFault int - -// ErrorFault enumeration values -const ( - FaultUnknown ErrorFault = iota - FaultServer - FaultClient -) - -func (f ErrorFault) String() string { - switch f { - case FaultServer: - return "server" - case FaultClient: - return "client" - default: - return "unknown" - } -} - -// SerializationError represents an error that occurred while attempting to serialize a request -type SerializationError struct { - Err error // original error -} - -// Error returns a formatted error for SerializationError -func (e *SerializationError) Error() string { - const msg = "serialization failed" - if e.Err == nil { - return msg - } - return fmt.Sprintf("%s: %v", msg, e.Err) -} - -// Unwrap returns the underlying Error in SerializationError -func (e *SerializationError) Unwrap() error { return e.Err } - -// CanceledError is the error that will be returned by an API request that was -// canceled. API operations given a Context may return this error when -// canceled. -type CanceledError struct { - Err error -} - -// CanceledError returns true to satisfy interfaces checking for canceled errors. -func (*CanceledError) CanceledError() bool { return true } - -// Unwrap returns the underlying error, if there was one. -func (e *CanceledError) Unwrap() error { - return e.Err -} - -func (e *CanceledError) Error() string { - return fmt.Sprintf("canceled, %v", e.Err) -} diff --git a/vendor/github.com/aws/smithy-go/go_module_metadata.go b/vendor/github.com/aws/smithy-go/go_module_metadata.go deleted file mode 100644 index b6c4c2f..0000000 --- a/vendor/github.com/aws/smithy-go/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package smithy - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.24.0" diff --git a/vendor/github.com/aws/smithy-go/internal/sync/singleflight/LICENSE b/vendor/github.com/aws/smithy-go/internal/sync/singleflight/LICENSE deleted file mode 100644 index fe6a620..0000000 --- a/vendor/github.com/aws/smithy-go/internal/sync/singleflight/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -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 COPYIGHT 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/vendor/github.com/aws/smithy-go/internal/sync/singleflight/docs.go b/vendor/github.com/aws/smithy-go/internal/sync/singleflight/docs.go deleted file mode 100644 index 9c9d02b..0000000 --- a/vendor/github.com/aws/smithy-go/internal/sync/singleflight/docs.go +++ /dev/null @@ -1,8 +0,0 @@ -// Package singleflight provides a duplicate function call suppression -// mechanism. This package is a fork of the Go golang.org/x/sync/singleflight -// package. The package is forked, because the package a part of the unstable -// and unversioned golang.org/x/sync module. -// -// https://github.com/golang/sync/tree/67f06af15bc961c363a7260195bcd53487529a21/singleflight - -package singleflight diff --git a/vendor/github.com/aws/smithy-go/internal/sync/singleflight/singleflight.go b/vendor/github.com/aws/smithy-go/internal/sync/singleflight/singleflight.go deleted file mode 100644 index e8a1b17..0000000 --- a/vendor/github.com/aws/smithy-go/internal/sync/singleflight/singleflight.go +++ /dev/null @@ -1,210 +0,0 @@ -// 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. - -package singleflight - -import ( - "bytes" - "errors" - "fmt" - "runtime" - "runtime/debug" - "sync" -) - -// errGoexit indicates the runtime.Goexit was called in -// the user given function. -var errGoexit = errors.New("runtime.Goexit was called") - -// A panicError is an arbitrary value recovered from a panic -// with the stack trace during the execution of given function. -type panicError struct { - value interface{} - stack []byte -} - -// Error implements error interface. -func (p *panicError) Error() string { - return fmt.Sprintf("%v\n\n%s", p.value, p.stack) -} - -func newPanicError(v interface{}) error { - stack := debug.Stack() - - // The first line of the stack trace is of the form "goroutine N [status]:" - // but by the time the panic reaches Do the goroutine may no longer exist - // and its status will have changed. Trim out the misleading line. - if line := bytes.IndexByte(stack[:], '\n'); line >= 0 { - stack = stack[line+1:] - } - return &panicError{value: v, stack: stack} -} - -// call is an in-flight or completed singleflight.Do call -type call struct { - wg sync.WaitGroup - - // These fields are written once before the WaitGroup is done - // and are only read after the WaitGroup is done. - val interface{} - err error - - // forgotten indicates whether Forget was called with this call's key - // while the call was still in flight. - forgotten bool - - // These fields are read and written with the singleflight - // mutex held before the WaitGroup is done, and are read but - // not written after the WaitGroup is done. - dups int - chans []chan<- Result -} - -// Group represents a class of work and forms a namespace in -// which units of work can be executed with duplicate suppression. -type Group struct { - mu sync.Mutex // protects m - m map[string]*call // lazily initialized -} - -// Result holds the results of Do, so they can be passed -// on a channel. -type Result struct { - Val interface{} - Err error - Shared bool -} - -// Do executes and returns the results of the given function, making -// sure that only one execution is in-flight for a given key at a -// time. If a duplicate comes in, the duplicate caller waits for the -// original to complete and receives the same results. -// The return value shared indicates whether v was given to multiple callers. -func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) { - g.mu.Lock() - if g.m == nil { - g.m = make(map[string]*call) - } - if c, ok := g.m[key]; ok { - c.dups++ - g.mu.Unlock() - c.wg.Wait() - - if e, ok := c.err.(*panicError); ok { - panic(e) - } else if c.err == errGoexit { - runtime.Goexit() - } - return c.val, c.err, true - } - c := new(call) - c.wg.Add(1) - g.m[key] = c - g.mu.Unlock() - - g.doCall(c, key, fn) - return c.val, c.err, c.dups > 0 -} - -// DoChan is like Do but returns a channel that will receive the -// results when they are ready. -// -// The returned channel will not be closed. -func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result { - ch := make(chan Result, 1) - g.mu.Lock() - if g.m == nil { - g.m = make(map[string]*call) - } - if c, ok := g.m[key]; ok { - c.dups++ - c.chans = append(c.chans, ch) - g.mu.Unlock() - return ch - } - c := &call{chans: []chan<- Result{ch}} - c.wg.Add(1) - g.m[key] = c - g.mu.Unlock() - - go g.doCall(c, key, fn) - - return ch -} - -// doCall handles the single call for a key. -func (g *Group) doCall(c *call, key string, fn func() (interface{}, error)) { - normalReturn := false - recovered := false - - // use double-defer to distinguish panic from runtime.Goexit, - // more details see https://golang.org/cl/134395 - defer func() { - // the given function invoked runtime.Goexit - if !normalReturn && !recovered { - c.err = errGoexit - } - - c.wg.Done() - g.mu.Lock() - defer g.mu.Unlock() - if !c.forgotten { - delete(g.m, key) - } - - if e, ok := c.err.(*panicError); ok { - // In order to prevent the waiting channels from being blocked forever, - // needs to ensure that this panic cannot be recovered. - if len(c.chans) > 0 { - go panic(e) - select {} // Keep this goroutine around so that it will appear in the crash dump. - } else { - panic(e) - } - } else if c.err == errGoexit { - // Already in the process of goexit, no need to call again - } else { - // Normal return - for _, ch := range c.chans { - ch <- Result{c.val, c.err, c.dups > 0} - } - } - }() - - func() { - defer func() { - if !normalReturn { - // Ideally, we would wait to take a stack trace until we've determined - // whether this is a panic or a runtime.Goexit. - // - // Unfortunately, the only way we can distinguish the two is to see - // whether the recover stopped the goroutine from terminating, and by - // the time we know that, the part of the stack trace relevant to the - // panic has been discarded. - if r := recover(); r != nil { - c.err = newPanicError(r) - } - } - }() - - c.val, c.err = fn() - normalReturn = true - }() - - if !normalReturn { - recovered = true - } -} - -// Forget tells the singleflight to forget about a key. Future calls -// to Do for this key will call the function rather than waiting for -// an earlier call to complete. -func (g *Group) Forget(key string) { - g.mu.Lock() - if c, ok := g.m[key]; ok { - c.forgotten = true - } - delete(g.m, key) - g.mu.Unlock() -} diff --git a/vendor/github.com/aws/smithy-go/io/byte.go b/vendor/github.com/aws/smithy-go/io/byte.go deleted file mode 100644 index f8417c1..0000000 --- a/vendor/github.com/aws/smithy-go/io/byte.go +++ /dev/null @@ -1,12 +0,0 @@ -package io - -const ( - // Byte is 8 bits - Byte int64 = 1 - // KibiByte (KiB) is 1024 Bytes - KibiByte = Byte * 1024 - // MebiByte (MiB) is 1024 KiB - MebiByte = KibiByte * 1024 - // GibiByte (GiB) is 1024 MiB - GibiByte = MebiByte * 1024 -) diff --git a/vendor/github.com/aws/smithy-go/io/doc.go b/vendor/github.com/aws/smithy-go/io/doc.go deleted file mode 100644 index a6a33ea..0000000 --- a/vendor/github.com/aws/smithy-go/io/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package io provides utilities for Smithy generated API clients. -package io diff --git a/vendor/github.com/aws/smithy-go/io/reader.go b/vendor/github.com/aws/smithy-go/io/reader.go deleted file mode 100644 index 07063f2..0000000 --- a/vendor/github.com/aws/smithy-go/io/reader.go +++ /dev/null @@ -1,16 +0,0 @@ -package io - -import ( - "io" -) - -// ReadSeekNopCloser wraps an io.ReadSeeker with an additional Close method -// that does nothing. -type ReadSeekNopCloser struct { - io.ReadSeeker -} - -// Close does nothing. -func (ReadSeekNopCloser) Close() error { - return nil -} diff --git a/vendor/github.com/aws/smithy-go/io/ringbuffer.go b/vendor/github.com/aws/smithy-go/io/ringbuffer.go deleted file mode 100644 index 06b476a..0000000 --- a/vendor/github.com/aws/smithy-go/io/ringbuffer.go +++ /dev/null @@ -1,94 +0,0 @@ -package io - -import ( - "bytes" - "io" -) - -// RingBuffer struct satisfies io.ReadWrite interface. -// -// ReadBuffer is a revolving buffer data structure, which can be used to store snapshots of data in a -// revolving window. -type RingBuffer struct { - slice []byte - start int - end int - size int -} - -// NewRingBuffer method takes in a byte slice as an input and returns a RingBuffer. -func NewRingBuffer(slice []byte) *RingBuffer { - ringBuf := RingBuffer{ - slice: slice, - } - return &ringBuf -} - -// Write method inserts the elements in a byte slice, and returns the number of bytes written along with any error. -func (r *RingBuffer) Write(p []byte) (int, error) { - for _, b := range p { - // check if end points to invalid index, we need to circle back - if r.end == len(r.slice) { - r.end = 0 - } - // check if start points to invalid index, we need to circle back - if r.start == len(r.slice) { - r.start = 0 - } - // if ring buffer is filled, increment the start index - if r.size == len(r.slice) { - r.size-- - r.start++ - } - - r.slice[r.end] = b - r.end++ - r.size++ - } - return len(p), nil -} - -// Read copies the data on the ring buffer into the byte slice provided to the method. -// Returns the read count along with any error encountered while reading. -func (r *RingBuffer) Read(p []byte) (int, error) { - // readCount keeps track of the number of bytes read - var readCount int - for j := 0; j < len(p); j++ { - // if ring buffer is empty or completely read - // return EOF error. - if r.size == 0 { - return readCount, io.EOF - } - - if r.start == len(r.slice) { - r.start = 0 - } - - p[j] = r.slice[r.start] - readCount++ - // increment the start pointer for ring buffer - r.start++ - // decrement the size of ring buffer - r.size-- - } - return readCount, nil -} - -// Len returns the number of unread bytes in the buffer. -func (r *RingBuffer) Len() int { - return r.size -} - -// Bytes returns a copy of the RingBuffer's bytes. -func (r RingBuffer) Bytes() []byte { - var b bytes.Buffer - io.Copy(&b, &r) - return b.Bytes() -} - -// Reset resets the ring buffer. -func (r *RingBuffer) Reset() { - *r = RingBuffer{ - slice: r.slice, - } -} diff --git a/vendor/github.com/aws/smithy-go/local-mod-replace.sh b/vendor/github.com/aws/smithy-go/local-mod-replace.sh deleted file mode 100644 index 800bf37..0000000 --- a/vendor/github.com/aws/smithy-go/local-mod-replace.sh +++ /dev/null @@ -1,39 +0,0 @@ -#1/usr/bin/env bash - -PROJECT_DIR="" -SMITHY_SOURCE_DIR=$(cd `dirname $0` && pwd) - -usage() { - echo "Usage: $0 [-s SMITHY_SOURCE_DIR] [-d PROJECT_DIR]" 1>&2 - exit 1 -} - -while getopts "hs:d:" options; do - case "${options}" in - s) - SMITHY_SOURCE_DIR=${OPTARG} - if [ "$SMITHY_SOURCE_DIR" == "" ]; then - echo "path to smithy-go source directory is required" || exit - usage - fi - ;; - d) - PROJECT_DIR=${OPTARG} - ;; - h) - usage - ;; - *) - usage - ;; - esac -done - -if [ "$PROJECT_DIR" != "" ]; then - cd $PROJECT_DIR || exit -fi - -go mod graph | awk '{print $1}' | cut -d '@' -f 1 | sort | uniq | grep "github.com/aws/smithy-go" | while read x; do - repPath=${x/github.com\/aws\/smithy-go/${SMITHY_SOURCE_DIR}} - echo -replace $x=$repPath -done | xargs go mod edit diff --git a/vendor/github.com/aws/smithy-go/logging/logger.go b/vendor/github.com/aws/smithy-go/logging/logger.go deleted file mode 100644 index 2071924..0000000 --- a/vendor/github.com/aws/smithy-go/logging/logger.go +++ /dev/null @@ -1,82 +0,0 @@ -package logging - -import ( - "context" - "io" - "log" -) - -// Classification is the type of the log entry's classification name. -type Classification string - -// Set of standard classifications that can be used by clients and middleware -const ( - Warn Classification = "WARN" - Debug Classification = "DEBUG" -) - -// Logger is an interface for logging entries at certain classifications. -type Logger interface { - // Logf is expected to support the standard fmt package "verbs". - Logf(classification Classification, format string, v ...interface{}) -} - -// LoggerFunc is a wrapper around a function to satisfy the Logger interface. -type LoggerFunc func(classification Classification, format string, v ...interface{}) - -// Logf delegates the logging request to the wrapped function. -func (f LoggerFunc) Logf(classification Classification, format string, v ...interface{}) { - f(classification, format, v...) -} - -// ContextLogger is an optional interface a Logger implementation may expose that provides -// the ability to create context aware log entries. -type ContextLogger interface { - WithContext(context.Context) Logger -} - -// WithContext will pass the provided context to logger if it implements the ContextLogger interface and return the resulting -// logger. Otherwise the logger will be returned as is. As a special case if a nil logger is provided, a Nop logger will -// be returned to the caller. -func WithContext(ctx context.Context, logger Logger) Logger { - if logger == nil { - return Nop{} - } - - cl, ok := logger.(ContextLogger) - if !ok { - return logger - } - - return cl.WithContext(ctx) -} - -// Nop is a Logger implementation that simply does not perform any logging. -type Nop struct{} - -// Logf simply returns without performing any action -func (n Nop) Logf(Classification, string, ...interface{}) { - return -} - -// StandardLogger is a Logger implementation that wraps the standard library logger, and delegates logging to it's -// Printf method. -type StandardLogger struct { - Logger *log.Logger -} - -// Logf logs the given classification and message to the underlying logger. -func (s StandardLogger) Logf(classification Classification, format string, v ...interface{}) { - if len(classification) != 0 { - format = string(classification) + " " + format - } - - s.Logger.Printf(format, v...) -} - -// NewStandardLogger returns a new StandardLogger -func NewStandardLogger(writer io.Writer) *StandardLogger { - return &StandardLogger{ - Logger: log.New(writer, "SDK ", log.LstdFlags), - } -} diff --git a/vendor/github.com/aws/smithy-go/metrics/metrics.go b/vendor/github.com/aws/smithy-go/metrics/metrics.go deleted file mode 100644 index c009d9f..0000000 --- a/vendor/github.com/aws/smithy-go/metrics/metrics.go +++ /dev/null @@ -1,136 +0,0 @@ -// Package metrics defines the metrics APIs used by Smithy clients. -package metrics - -import ( - "context" - - "github.com/aws/smithy-go" -) - -// MeterProvider is the entry point for creating a Meter. -type MeterProvider interface { - Meter(scope string, opts ...MeterOption) Meter -} - -// MeterOption applies configuration to a Meter. -type MeterOption func(o *MeterOptions) - -// MeterOptions represents configuration for a Meter. -type MeterOptions struct { - Properties smithy.Properties -} - -// Meter is the entry point for creation of measurement instruments. -type Meter interface { - // integer/synchronous - Int64Counter(name string, opts ...InstrumentOption) (Int64Counter, error) - Int64UpDownCounter(name string, opts ...InstrumentOption) (Int64UpDownCounter, error) - Int64Gauge(name string, opts ...InstrumentOption) (Int64Gauge, error) - Int64Histogram(name string, opts ...InstrumentOption) (Int64Histogram, error) - - // integer/asynchronous - Int64AsyncCounter(name string, callback Int64Callback, opts ...InstrumentOption) (AsyncInstrument, error) - Int64AsyncUpDownCounter(name string, callback Int64Callback, opts ...InstrumentOption) (AsyncInstrument, error) - Int64AsyncGauge(name string, callback Int64Callback, opts ...InstrumentOption) (AsyncInstrument, error) - - // floating-point/synchronous - Float64Counter(name string, opts ...InstrumentOption) (Float64Counter, error) - Float64UpDownCounter(name string, opts ...InstrumentOption) (Float64UpDownCounter, error) - Float64Gauge(name string, opts ...InstrumentOption) (Float64Gauge, error) - Float64Histogram(name string, opts ...InstrumentOption) (Float64Histogram, error) - - // floating-point/asynchronous - Float64AsyncCounter(name string, callback Float64Callback, opts ...InstrumentOption) (AsyncInstrument, error) - Float64AsyncUpDownCounter(name string, callback Float64Callback, opts ...InstrumentOption) (AsyncInstrument, error) - Float64AsyncGauge(name string, callback Float64Callback, opts ...InstrumentOption) (AsyncInstrument, error) -} - -// InstrumentOption applies configuration to an instrument. -type InstrumentOption func(o *InstrumentOptions) - -// InstrumentOptions represents configuration for an instrument. -type InstrumentOptions struct { - UnitLabel string - Description string -} - -// Int64Counter measures a monotonically increasing int64 value. -type Int64Counter interface { - Add(context.Context, int64, ...RecordMetricOption) -} - -// Int64UpDownCounter measures a fluctuating int64 value. -type Int64UpDownCounter interface { - Add(context.Context, int64, ...RecordMetricOption) -} - -// Int64Gauge samples a discrete int64 value. -type Int64Gauge interface { - Sample(context.Context, int64, ...RecordMetricOption) -} - -// Int64Histogram records multiple data points for an int64 value. -type Int64Histogram interface { - Record(context.Context, int64, ...RecordMetricOption) -} - -// Float64Counter measures a monotonically increasing float64 value. -type Float64Counter interface { - Add(context.Context, float64, ...RecordMetricOption) -} - -// Float64UpDownCounter measures a fluctuating float64 value. -type Float64UpDownCounter interface { - Add(context.Context, float64, ...RecordMetricOption) -} - -// Float64Gauge samples a discrete float64 value. -type Float64Gauge interface { - Sample(context.Context, float64, ...RecordMetricOption) -} - -// Float64Histogram records multiple data points for an float64 value. -type Float64Histogram interface { - Record(context.Context, float64, ...RecordMetricOption) -} - -// AsyncInstrument is the universal handle returned for creation of all async -// instruments. -// -// Callers use the Stop() API to unregister the callback passed at instrument -// creation. -type AsyncInstrument interface { - Stop() -} - -// Int64Callback describes a function invoked when an async int64 instrument is -// read. -type Int64Callback func(context.Context, Int64Observer) - -// Int64Observer is the interface passed to async int64 instruments. -// -// Callers use the Observe() API of this interface to report metrics to the -// underlying collector. -type Int64Observer interface { - Observe(context.Context, int64, ...RecordMetricOption) -} - -// Float64Callback describes a function invoked when an async float64 -// instrument is read. -type Float64Callback func(context.Context, Float64Observer) - -// Float64Observer is the interface passed to async int64 instruments. -// -// Callers use the Observe() API of this interface to report metrics to the -// underlying collector. -type Float64Observer interface { - Observe(context.Context, float64, ...RecordMetricOption) -} - -// RecordMetricOption applies configuration to a recorded metric. -type RecordMetricOption func(o *RecordMetricOptions) - -// RecordMetricOptions represents configuration for a recorded metric. -type RecordMetricOptions struct { - Properties smithy.Properties -} diff --git a/vendor/github.com/aws/smithy-go/metrics/nop.go b/vendor/github.com/aws/smithy-go/metrics/nop.go deleted file mode 100644 index 444126d..0000000 --- a/vendor/github.com/aws/smithy-go/metrics/nop.go +++ /dev/null @@ -1,98 +0,0 @@ -package metrics - -import "context" - -// NopMeterProvider is a no-op metrics implementation. -type NopMeterProvider struct{} - -var _ MeterProvider = (*NopMeterProvider)(nil) - -// Meter returns a meter which creates no-op instruments. -func (NopMeterProvider) Meter(string, ...MeterOption) Meter { - return NopMeter{} -} - -// NopMeter creates no-op instruments. -type NopMeter struct{} - -var _ Meter = (*NopMeter)(nil) - -// Int64Counter creates a no-op instrument. -func (NopMeter) Int64Counter(string, ...InstrumentOption) (Int64Counter, error) { - return nopInstrumentInt64, nil -} - -// Int64UpDownCounter creates a no-op instrument. -func (NopMeter) Int64UpDownCounter(string, ...InstrumentOption) (Int64UpDownCounter, error) { - return nopInstrumentInt64, nil -} - -// Int64Gauge creates a no-op instrument. -func (NopMeter) Int64Gauge(string, ...InstrumentOption) (Int64Gauge, error) { - return nopInstrumentInt64, nil -} - -// Int64Histogram creates a no-op instrument. -func (NopMeter) Int64Histogram(string, ...InstrumentOption) (Int64Histogram, error) { - return nopInstrumentInt64, nil -} - -// Int64AsyncCounter creates a no-op instrument. -func (NopMeter) Int64AsyncCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrumentInt64, nil -} - -// Int64AsyncUpDownCounter creates a no-op instrument. -func (NopMeter) Int64AsyncUpDownCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrumentInt64, nil -} - -// Int64AsyncGauge creates a no-op instrument. -func (NopMeter) Int64AsyncGauge(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrumentInt64, nil -} - -// Float64Counter creates a no-op instrument. -func (NopMeter) Float64Counter(string, ...InstrumentOption) (Float64Counter, error) { - return nopInstrumentFloat64, nil -} - -// Float64UpDownCounter creates a no-op instrument. -func (NopMeter) Float64UpDownCounter(string, ...InstrumentOption) (Float64UpDownCounter, error) { - return nopInstrumentFloat64, nil -} - -// Float64Gauge creates a no-op instrument. -func (NopMeter) Float64Gauge(string, ...InstrumentOption) (Float64Gauge, error) { - return nopInstrumentFloat64, nil -} - -// Float64Histogram creates a no-op instrument. -func (NopMeter) Float64Histogram(string, ...InstrumentOption) (Float64Histogram, error) { - return nopInstrumentFloat64, nil -} - -// Float64AsyncCounter creates a no-op instrument. -func (NopMeter) Float64AsyncCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrumentFloat64, nil -} - -// Float64AsyncUpDownCounter creates a no-op instrument. -func (NopMeter) Float64AsyncUpDownCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrumentFloat64, nil -} - -// Float64AsyncGauge creates a no-op instrument. -func (NopMeter) Float64AsyncGauge(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrumentFloat64, nil -} - -type nopInstrument[N any] struct{} - -func (nopInstrument[N]) Add(context.Context, N, ...RecordMetricOption) {} -func (nopInstrument[N]) Sample(context.Context, N, ...RecordMetricOption) {} -func (nopInstrument[N]) Record(context.Context, N, ...RecordMetricOption) {} -func (nopInstrument[_]) Stop() {} - -var nopInstrumentInt64 = nopInstrument[int64]{} -var nopInstrumentFloat64 = nopInstrument[float64]{} diff --git a/vendor/github.com/aws/smithy-go/middleware/context.go b/vendor/github.com/aws/smithy-go/middleware/context.go deleted file mode 100644 index f51aa4f..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/context.go +++ /dev/null @@ -1,41 +0,0 @@ -package middleware - -import "context" - -type ( - serviceIDKey struct{} - operationNameKey struct{} -) - -// WithServiceID adds a service ID to the context, scoped to middleware stack -// values. -// -// This API is called in the client runtime when bootstrapping an operation and -// should not typically be used directly. -func WithServiceID(parent context.Context, id string) context.Context { - return WithStackValue(parent, serviceIDKey{}, id) -} - -// GetServiceID retrieves the service ID from the context. This is typically -// the service shape's name from its Smithy model. Service clients for specific -// systems (e.g. AWS SDK) may use an alternate designated value. -func GetServiceID(ctx context.Context) string { - id, _ := GetStackValue(ctx, serviceIDKey{}).(string) - return id -} - -// WithOperationName adds the operation name to the context, scoped to -// middleware stack values. -// -// This API is called in the client runtime when bootstrapping an operation and -// should not typically be used directly. -func WithOperationName(parent context.Context, id string) context.Context { - return WithStackValue(parent, operationNameKey{}, id) -} - -// GetOperationName retrieves the operation name from the context. This is -// typically the operation shape's name from its Smithy model. -func GetOperationName(ctx context.Context) string { - name, _ := GetStackValue(ctx, operationNameKey{}).(string) - return name -} diff --git a/vendor/github.com/aws/smithy-go/middleware/doc.go b/vendor/github.com/aws/smithy-go/middleware/doc.go deleted file mode 100644 index 9858928..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/doc.go +++ /dev/null @@ -1,67 +0,0 @@ -// Package middleware provides transport agnostic middleware for decorating SDK -// handlers. -// -// The Smithy middleware stack provides ordered behavior to be invoked on an -// underlying handler. The stack is separated into steps that are invoked in a -// static order. A step is a collection of middleware that are injected into a -// ordered list defined by the user. The user may add, insert, swap, and remove a -// step's middleware. When the stack is invoked the step middleware become static, -// and their order cannot be modified. -// -// A stack and its step middleware are **not** safe to modify concurrently. -// -// A stack will use the ordered list of middleware to decorate a underlying -// handler. A handler could be something like an HTTP Client that round trips an -// API operation over HTTP. -// -// Smithy Middleware Stack -// -// A Stack is a collection of middleware that wrap a handler. The stack can be -// broken down into discreet steps. Each step may contain zero or more middleware -// specific to that stack's step. -// -// A Stack Step is a predefined set of middleware that are invoked in a static -// order by the Stack. These steps represent fixed points in the middleware stack -// for organizing specific behavior, such as serialize and build. A Stack Step is -// composed of zero or more middleware that are specific to that step. A step may -// define its own set of input/output parameters the generic input/output -// parameters are cast from. A step calls its middleware recursively, before -// calling the next step in the stack returning the result or error of the step -// middleware decorating the underlying handler. -// -// * Initialize: Prepares the input, and sets any default parameters as needed, -// (e.g. idempotency token, and presigned URLs). -// -// * Serialize: Serializes the prepared input into a data structure that can be -// consumed by the target transport's message, (e.g. REST-JSON serialization). -// -// * Build: Adds additional metadata to the serialized transport message, (e.g. -// HTTP's Content-Length header, or body checksum). Decorations and -// modifications to the message should be copied to all message attempts. -// -// * Finalize: Performs final preparations needed before sending the message. The -// message should already be complete by this stage, and is only alternated to -// meet the expectations of the recipient, (e.g. Retry and AWS SigV4 request -// signing). -// -// * Deserialize: Reacts to the handler's response returned by the recipient of -// the request message. Deserializes the response into a structured type or -// error above stacks can react to. -// -// Adding Middleware to a Stack Step -// -// Middleware can be added to a step front or back, or relative, by name, to an -// existing middleware in that stack. If a middleware does not have a name, a -// unique name will be generated at the middleware and be added to the step. -// -// // Create middleware stack -// stack := middleware.NewStack() -// -// // Add middleware to stack steps -// stack.Initialize.Add(paramValidationMiddleware, middleware.After) -// stack.Serialize.Add(marshalOperationFoo, middleware.After) -// stack.Deserialize.Add(unmarshalOperationFoo, middleware.After) -// -// // Invoke middleware on handler. -// resp, err := stack.HandleMiddleware(ctx, req.Input, clientHandler) -package middleware diff --git a/vendor/github.com/aws/smithy-go/middleware/logging.go b/vendor/github.com/aws/smithy-go/middleware/logging.go deleted file mode 100644 index c2f0dbb..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/logging.go +++ /dev/null @@ -1,46 +0,0 @@ -package middleware - -import ( - "context" - - "github.com/aws/smithy-go/logging" -) - -// loggerKey is the context value key for which the logger is associated with. -type loggerKey struct{} - -// GetLogger takes a context to retrieve a Logger from. If no logger is present on the context a logging.Nop logger -// is returned. If the logger retrieved from context supports the ContextLogger interface, the context will be passed -// to the WithContext method and the resulting logger will be returned. Otherwise the stored logger is returned as is. -func GetLogger(ctx context.Context) logging.Logger { - logger, ok := ctx.Value(loggerKey{}).(logging.Logger) - if !ok || logger == nil { - return logging.Nop{} - } - - return logging.WithContext(ctx, logger) -} - -// SetLogger sets the provided logger value on the provided ctx. -func SetLogger(ctx context.Context, logger logging.Logger) context.Context { - return context.WithValue(ctx, loggerKey{}, logger) -} - -type setLogger struct { - Logger logging.Logger -} - -// AddSetLoggerMiddleware adds a middleware that will add the provided logger to the middleware context. -func AddSetLoggerMiddleware(stack *Stack, logger logging.Logger) error { - return stack.Initialize.Add(&setLogger{Logger: logger}, After) -} - -func (a *setLogger) ID() string { - return "SetLogger" -} - -func (a *setLogger) HandleInitialize(ctx context.Context, in InitializeInput, next InitializeHandler) ( - out InitializeOutput, metadata Metadata, err error, -) { - return next.HandleInitialize(SetLogger(ctx, a.Logger), in) -} diff --git a/vendor/github.com/aws/smithy-go/middleware/metadata.go b/vendor/github.com/aws/smithy-go/middleware/metadata.go deleted file mode 100644 index 7bb7dbc..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/metadata.go +++ /dev/null @@ -1,65 +0,0 @@ -package middleware - -// MetadataReader provides an interface for reading metadata from the -// underlying metadata container. -type MetadataReader interface { - Get(key interface{}) interface{} -} - -// Metadata provides storing and reading metadata values. Keys may be any -// comparable value type. Get and set will panic if key is not a comparable -// value type. -// -// Metadata uses lazy initialization, and Set method must be called as an -// addressable value, or pointer. Not doing so may cause key/value pair to not -// be set. -type Metadata struct { - values map[interface{}]interface{} -} - -// Get attempts to retrieve the value the key points to. Returns nil if the -// key was not found. -// -// Panics if key type is not comparable. -func (m Metadata) Get(key interface{}) interface{} { - return m.values[key] -} - -// Clone creates a shallow copy of Metadata entries, returning a new Metadata -// value with the original entries copied into it. -func (m Metadata) Clone() Metadata { - vs := make(map[interface{}]interface{}, len(m.values)) - for k, v := range m.values { - vs[k] = v - } - - return Metadata{ - values: vs, - } -} - -// Set stores the value pointed to by the key. If a value already exists at -// that key it will be replaced with the new value. -// -// Set method must be called as an addressable value, or pointer. If Set is not -// called as an addressable value or pointer, the key value pair being set may -// be lost. -// -// Panics if the key type is not comparable. -func (m *Metadata) Set(key, value interface{}) { - if m.values == nil { - m.values = map[interface{}]interface{}{} - } - m.values[key] = value -} - -// Has returns whether the key exists in the metadata. -// -// Panics if the key type is not comparable. -func (m Metadata) Has(key interface{}) bool { - if m.values == nil { - return false - } - _, ok := m.values[key] - return ok -} diff --git a/vendor/github.com/aws/smithy-go/middleware/middleware.go b/vendor/github.com/aws/smithy-go/middleware/middleware.go deleted file mode 100644 index 803b7c7..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/middleware.go +++ /dev/null @@ -1,71 +0,0 @@ -package middleware - -import ( - "context" -) - -// Handler provides the interface for performing the logic to obtain an output, -// or error for the given input. -type Handler interface { - // Handle performs logic to obtain an output for the given input. Handler - // should be decorated with middleware to perform input specific behavior. - Handle(ctx context.Context, input interface{}) ( - output interface{}, metadata Metadata, err error, - ) -} - -// HandlerFunc provides a wrapper around a function pointer to be used as a -// middleware handler. -type HandlerFunc func(ctx context.Context, input interface{}) ( - output interface{}, metadata Metadata, err error, -) - -// Handle invokes the underlying function, returning the result. -func (fn HandlerFunc) Handle(ctx context.Context, input interface{}) ( - output interface{}, metadata Metadata, err error, -) { - return fn(ctx, input) -} - -// Middleware provides the interface to call handlers in a chain. -type Middleware interface { - // ID provides a unique identifier for the middleware. - ID() string - - // Performs the middleware's handling of the input, returning the output, - // or error. The middleware can invoke the next Handler if handling should - // continue. - HandleMiddleware(ctx context.Context, input interface{}, next Handler) ( - output interface{}, metadata Metadata, err error, - ) -} - -// decoratedHandler wraps a middleware in order to to call the next handler in -// the chain. -type decoratedHandler struct { - // The next handler to be called. - Next Handler - - // The current middleware decorating the handler. - With Middleware -} - -// Handle implements the Handler interface to handle a operation invocation. -func (m decoratedHandler) Handle(ctx context.Context, input interface{}) ( - output interface{}, metadata Metadata, err error, -) { - return m.With.HandleMiddleware(ctx, input, m.Next) -} - -// DecorateHandler decorates a handler with a middleware. Wrapping the handler -// with the middleware. -func DecorateHandler(h Handler, with ...Middleware) Handler { - for i := len(with) - 1; i >= 0; i-- { - h = decoratedHandler{ - Next: h, - With: with[i], - } - } - - return h -} diff --git a/vendor/github.com/aws/smithy-go/middleware/ordered_group.go b/vendor/github.com/aws/smithy-go/middleware/ordered_group.go deleted file mode 100644 index daf9013..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/ordered_group.go +++ /dev/null @@ -1,270 +0,0 @@ -package middleware - -import "fmt" - -// RelativePosition provides specifying the relative position of a middleware -// in an ordered group. -type RelativePosition int - -// Relative position for middleware in steps. -const ( - After RelativePosition = iota - Before -) - -type ider interface { - ID() string -} - -// orderedIDs provides an ordered collection of items with relative ordering -// by name. -type orderedIDs struct { - order *relativeOrder - items map[string]ider -} - -// selected based on the general upper bound of # of middlewares in each step -// in the downstream aws-sdk-go-v2 -const baseOrderedItems = 8 - -func newOrderedIDs(cap int) *orderedIDs { - return &orderedIDs{ - order: newRelativeOrder(cap), - items: make(map[string]ider, cap), - } -} - -// Add injects the item to the relative position of the item group. Returns an -// error if the item already exists. -func (g *orderedIDs) Add(m ider, pos RelativePosition) error { - id := m.ID() - if len(id) == 0 { - return fmt.Errorf("empty ID, ID must not be empty") - } - - if err := g.order.Add(pos, id); err != nil { - return err - } - - g.items[id] = m - return nil -} - -// Insert injects the item relative to an existing item id. Returns an error if -// the original item does not exist, or the item being added already exists. -func (g *orderedIDs) Insert(m ider, relativeTo string, pos RelativePosition) error { - if len(m.ID()) == 0 { - return fmt.Errorf("insert ID must not be empty") - } - if len(relativeTo) == 0 { - return fmt.Errorf("relative to ID must not be empty") - } - - if err := g.order.Insert(relativeTo, pos, m.ID()); err != nil { - return err - } - - g.items[m.ID()] = m - return nil -} - -// Get returns the ider identified by id. If ider is not present, returns false. -func (g *orderedIDs) Get(id string) (ider, bool) { - v, ok := g.items[id] - return v, ok -} - -// Swap removes the item by id, replacing it with the new item. Returns an error -// if the original item doesn't exist. -func (g *orderedIDs) Swap(id string, m ider) (ider, error) { - if len(id) == 0 { - return nil, fmt.Errorf("swap from ID must not be empty") - } - - iderID := m.ID() - if len(iderID) == 0 { - return nil, fmt.Errorf("swap to ID must not be empty") - } - - if err := g.order.Swap(id, iderID); err != nil { - return nil, err - } - - removed := g.items[id] - - delete(g.items, id) - g.items[iderID] = m - - return removed, nil -} - -// Remove removes the item by id. Returns an error if the item -// doesn't exist. -func (g *orderedIDs) Remove(id string) (ider, error) { - if len(id) == 0 { - return nil, fmt.Errorf("remove ID must not be empty") - } - - if err := g.order.Remove(id); err != nil { - return nil, err - } - - removed := g.items[id] - delete(g.items, id) - return removed, nil -} - -func (g *orderedIDs) List() []string { - items := g.order.List() - order := make([]string, len(items)) - copy(order, items) - return order -} - -// Clear removes all entries and slots. -func (g *orderedIDs) Clear() { - g.order.Clear() - g.items = map[string]ider{} -} - -// GetOrder returns the item in the order it should be invoked in. -func (g *orderedIDs) GetOrder() []interface{} { - order := g.order.List() - ordered := make([]interface{}, len(order)) - for i := 0; i < len(order); i++ { - ordered[i] = g.items[order[i]] - } - - return ordered -} - -// relativeOrder provides ordering of item -type relativeOrder struct { - order []string -} - -func newRelativeOrder(cap int) *relativeOrder { - return &relativeOrder{ - order: make([]string, 0, cap), - } -} - -// Add inserts an item into the order relative to the position provided. -func (s *relativeOrder) Add(pos RelativePosition, ids ...string) error { - if len(ids) == 0 { - return nil - } - - for _, id := range ids { - if _, ok := s.has(id); ok { - return fmt.Errorf("already exists, %v", id) - } - } - - switch pos { - case Before: - return s.insert(0, Before, ids...) - - case After: - s.order = append(s.order, ids...) - - default: - return fmt.Errorf("invalid position, %v", int(pos)) - } - - return nil -} - -// Insert injects an item before or after the relative item. Returns -// an error if the relative item does not exist. -func (s *relativeOrder) Insert(relativeTo string, pos RelativePosition, ids ...string) error { - if len(ids) == 0 { - return nil - } - - for _, id := range ids { - if _, ok := s.has(id); ok { - return fmt.Errorf("already exists, %v", id) - } - } - - i, ok := s.has(relativeTo) - if !ok { - return fmt.Errorf("not found, %v", relativeTo) - } - - return s.insert(i, pos, ids...) -} - -// Swap will replace the item id with the to item. Returns an -// error if the original item id does not exist. Allows swapping out an -// item for another item with the same id. -func (s *relativeOrder) Swap(id, to string) error { - i, ok := s.has(id) - if !ok { - return fmt.Errorf("not found, %v", id) - } - - if _, ok = s.has(to); ok && id != to { - return fmt.Errorf("already exists, %v", to) - } - - s.order[i] = to - return nil -} - -func (s *relativeOrder) Remove(id string) error { - i, ok := s.has(id) - if !ok { - return fmt.Errorf("not found, %v", id) - } - - s.order = append(s.order[:i], s.order[i+1:]...) - return nil -} - -func (s *relativeOrder) List() []string { - return s.order -} - -func (s *relativeOrder) Clear() { - s.order = s.order[0:0] -} - -func (s *relativeOrder) insert(i int, pos RelativePosition, ids ...string) error { - switch pos { - case Before: - n := len(ids) - var src []string - if n <= cap(s.order)-len(s.order) { - s.order = s.order[:len(s.order)+n] - src = s.order - } else { - src = s.order - s.order = make([]string, len(s.order)+n) - copy(s.order[:i], src[:i]) // only when allocating a new slice do we need to copy the front half - } - copy(s.order[i+n:], src[i:]) - copy(s.order[i:], ids) - case After: - if i == len(s.order)-1 || len(s.order) == 0 { - s.order = append(s.order, ids...) - } else { - s.order = append(s.order[:i+1], append(ids, s.order[i+1:]...)...) - } - - default: - return fmt.Errorf("invalid position, %v", int(pos)) - } - - return nil -} - -func (s *relativeOrder) has(id string) (i int, found bool) { - for i := 0; i < len(s.order); i++ { - if s.order[i] == id { - return i, true - } - } - return 0, false -} diff --git a/vendor/github.com/aws/smithy-go/middleware/stack.go b/vendor/github.com/aws/smithy-go/middleware/stack.go deleted file mode 100644 index 45ccb5b..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/stack.go +++ /dev/null @@ -1,209 +0,0 @@ -package middleware - -import ( - "context" - "io" - "strings" -) - -// Stack provides protocol and transport agnostic set of middleware split into -// distinct steps. Steps have specific transitions between them, that are -// managed by the individual step. -// -// Steps are composed as middleware around the underlying handler in the -// following order: -// -// Initialize -> Serialize -> Build -> Finalize -> Deserialize -> Handler -// -// Any middleware within the chain may choose to stop and return an error or -// response. Since the middleware decorate the handler like a call stack, each -// middleware will receive the result of the next middleware in the chain. -// Middleware that does not need to react to an input, or result must forward -// along the input down the chain, or return the result back up the chain. -// -// Initialize <- Serialize -> Build -> Finalize <- Deserialize <- Handler -type Stack struct { - // Initialize prepares the input, and sets any default parameters as - // needed, (e.g. idempotency token, and presigned URLs). - // - // Takes Input Parameters, and returns result or error. - // - // Receives result or error from Serialize step. - Initialize *InitializeStep - - // Serialize serializes the prepared input into a data structure that can be consumed - // by the target transport's message, (e.g. REST-JSON serialization) - // - // Converts Input Parameters into a Request, and returns the result or error. - // - // Receives result or error from Build step. - Serialize *SerializeStep - - // Build adds additional metadata to the serialized transport message - // (e.g. HTTP's Content-Length header, or body checksum). Decorations and - // modifications to the message should be copied to all message attempts. - // - // Takes Request, and returns result or error. - // - // Receives result or error from Finalize step. - Build *BuildStep - - // Finalize performs final preparations needed before sending the message. The - // message should already be complete by this stage, and is only alternated - // to meet the expectations of the recipient (e.g. Retry and AWS SigV4 - // request signing) - // - // Takes Request, and returns result or error. - // - // Receives result or error from Deserialize step. - Finalize *FinalizeStep - - // Deserialize reacts to the handler's response returned by the recipient of the request - // message. Deserializes the response into a structured type or error above - // stacks can react to. - // - // Should only forward Request to underlying handler. - // - // Takes Request, and returns result or error. - // - // Receives raw response, or error from underlying handler. - Deserialize *DeserializeStep - - id string -} - -// NewStack returns an initialize empty stack. -func NewStack(id string, newRequestFn func() interface{}) *Stack { - return &Stack{ - id: id, - Initialize: NewInitializeStep(), - Serialize: NewSerializeStep(newRequestFn), - Build: NewBuildStep(), - Finalize: NewFinalizeStep(), - Deserialize: NewDeserializeStep(), - } -} - -// ID returns the unique ID for the stack as a middleware. -func (s *Stack) ID() string { return s.id } - -// HandleMiddleware invokes the middleware stack decorating the next handler. -// Each step of stack will be invoked in order before calling the next step. -// With the next handler call last. -// -// The input value must be the input parameters of the operation being -// performed. -// -// Will return the result of the operation, or error. -func (s *Stack) HandleMiddleware(ctx context.Context, input interface{}, next Handler) ( - output interface{}, metadata Metadata, err error, -) { - h := DecorateHandler(next, - s.Initialize, - s.Serialize, - s.Build, - s.Finalize, - s.Deserialize, - ) - - return h.Handle(ctx, input) -} - -// List returns a list of all middleware in the stack by step. -func (s *Stack) List() []string { - var l []string - l = append(l, s.id) - - l = append(l, s.Initialize.ID()) - l = append(l, s.Initialize.List()...) - - l = append(l, s.Serialize.ID()) - l = append(l, s.Serialize.List()...) - - l = append(l, s.Build.ID()) - l = append(l, s.Build.List()...) - - l = append(l, s.Finalize.ID()) - l = append(l, s.Finalize.List()...) - - l = append(l, s.Deserialize.ID()) - l = append(l, s.Deserialize.List()...) - - return l -} - -func (s *Stack) String() string { - var b strings.Builder - - w := &indentWriter{w: &b} - - w.WriteLine(s.id) - w.Push() - - writeStepItems(w, s.Initialize) - writeStepItems(w, s.Serialize) - writeStepItems(w, s.Build) - writeStepItems(w, s.Finalize) - writeStepItems(w, s.Deserialize) - - return b.String() -} - -type stackStepper interface { - ID() string - List() []string -} - -func writeStepItems(w *indentWriter, s stackStepper) { - type lister interface { - List() []string - } - - w.WriteLine(s.ID()) - w.Push() - - defer w.Pop() - - // ignore stack to prevent circular iterations - if _, ok := s.(*Stack); ok { - return - } - - for _, id := range s.List() { - w.WriteLine(id) - } -} - -type stringWriter interface { - io.Writer - WriteString(string) (int, error) - WriteRune(rune) (int, error) -} - -type indentWriter struct { - w stringWriter - depth int -} - -const indentDepth = "\t\t\t\t\t\t\t\t\t\t" - -func (w *indentWriter) Push() { - w.depth++ -} - -func (w *indentWriter) Pop() { - w.depth-- - if w.depth < 0 { - w.depth = 0 - } -} - -func (w *indentWriter) WriteLine(v string) { - w.w.WriteString(indentDepth[:w.depth]) - - v = strings.ReplaceAll(v, "\n", "\\n") - v = strings.ReplaceAll(v, "\r", "\\r") - - w.w.WriteString(v) - w.w.WriteRune('\n') -} diff --git a/vendor/github.com/aws/smithy-go/middleware/stack_values.go b/vendor/github.com/aws/smithy-go/middleware/stack_values.go deleted file mode 100644 index ef96009..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/stack_values.go +++ /dev/null @@ -1,100 +0,0 @@ -package middleware - -import ( - "context" - "reflect" - "strings" -) - -// WithStackValue adds a key value pair to the context that is intended to be -// scoped to a stack. Use ClearStackValues to get a new context with all stack -// values cleared. -func WithStackValue(ctx context.Context, key, value interface{}) context.Context { - md, _ := ctx.Value(stackValuesKey{}).(*stackValues) - - md = withStackValue(md, key, value) - return context.WithValue(ctx, stackValuesKey{}, md) -} - -// ClearStackValues returns a context without any stack values. -func ClearStackValues(ctx context.Context) context.Context { - return context.WithValue(ctx, stackValuesKey{}, nil) -} - -// GetStackValues returns the value pointed to by the key within the stack -// values, if it is present. -func GetStackValue(ctx context.Context, key interface{}) interface{} { - md, _ := ctx.Value(stackValuesKey{}).(*stackValues) - if md == nil { - return nil - } - - return md.Value(key) -} - -type stackValuesKey struct{} - -type stackValues struct { - key interface{} - value interface{} - parent *stackValues -} - -func withStackValue(parent *stackValues, key, value interface{}) *stackValues { - if key == nil { - panic("nil key") - } - if !reflect.TypeOf(key).Comparable() { - panic("key is not comparable") - } - return &stackValues{key: key, value: value, parent: parent} -} - -func (m *stackValues) Value(key interface{}) interface{} { - if key == m.key { - return m.value - } - - if m.parent == nil { - return nil - } - - return m.parent.Value(key) -} - -func (c *stackValues) String() string { - var str strings.Builder - - cc := c - for cc == nil { - str.WriteString("(" + - reflect.TypeOf(c.key).String() + - ": " + - stringify(cc.value) + - ")") - if cc.parent != nil { - str.WriteString(" -> ") - } - cc = cc.parent - } - str.WriteRune('}') - - return str.String() -} - -type stringer interface { - String() string -} - -// stringify tries a bit to stringify v, without using fmt, since we don't -// want context depending on the unicode tables. This is only used by -// *valueCtx.String(). -func stringify(v interface{}) string { - switch s := v.(type) { - case stringer: - return s.String() - case string: - return s - } - return "" -} diff --git a/vendor/github.com/aws/smithy-go/middleware/step_build.go b/vendor/github.com/aws/smithy-go/middleware/step_build.go deleted file mode 100644 index db8c267..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/step_build.go +++ /dev/null @@ -1,298 +0,0 @@ -// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. -package middleware - -import ( - "context" - "fmt" -) - -// BuildInput provides the input parameters for the BuildMiddleware to consume. -// BuildMiddleware may modify the Request value before forwarding the input -// along to the next BuildHandler. -type BuildInput struct { - Request interface{} -} - -// BuildOutput provides the result returned by the next BuildHandler. -type BuildOutput struct { - Result interface{} -} - -// BuildHandler provides the interface for the next handler the -// BuildMiddleware will call in the middleware chain. -type BuildHandler interface { - HandleBuild(ctx context.Context, in BuildInput) ( - out BuildOutput, metadata Metadata, err error, - ) -} - -// BuildMiddleware provides the interface for middleware specific to the -// build step. Delegates to the next BuildHandler for further -// processing. -type BuildMiddleware interface { - // ID returns a unique ID for the middleware in the BuildStep. The step does not - // allow duplicate IDs. - ID() string - - // HandleBuild invokes the middleware behavior which must delegate to the next handler - // for the middleware chain to continue. The method must return a result or - // error to its caller. - HandleBuild(ctx context.Context, in BuildInput, next BuildHandler) ( - out BuildOutput, metadata Metadata, err error, - ) -} - -// BuildMiddlewareFunc returns a BuildMiddleware with the unique ID provided, -// and the func to be invoked. -func BuildMiddlewareFunc(id string, fn func(context.Context, BuildInput, BuildHandler) (BuildOutput, Metadata, error)) BuildMiddleware { - return buildMiddlewareFunc{ - id: id, - fn: fn, - } -} - -type buildMiddlewareFunc struct { - // Unique ID for the middleware. - id string - - // Middleware function to be called. - fn func(context.Context, BuildInput, BuildHandler) ( - BuildOutput, Metadata, error, - ) -} - -// ID returns the unique ID for the middleware. -func (s buildMiddlewareFunc) ID() string { return s.id } - -// HandleBuild invokes the middleware Fn. -func (s buildMiddlewareFunc) HandleBuild(ctx context.Context, in BuildInput, next BuildHandler) ( - out BuildOutput, metadata Metadata, err error, -) { - return s.fn(ctx, in, next) -} - -var _ BuildMiddleware = (buildMiddlewareFunc{}) - -// BuildStep provides the ordered grouping of BuildMiddleware to be -// invoked on a handler. -type BuildStep struct { - head *decoratedBuildHandler - tail *decoratedBuildHandler -} - -// NewBuildStep returns an BuildStep ready to have middleware for -// build added to it. -func NewBuildStep() *BuildStep { - return &BuildStep{} -} - -var _ Middleware = (*BuildStep)(nil) - -// ID returns the unique ID of the step as a middleware. -func (s *BuildStep) ID() string { - return "Build stack step" -} - -// HandleMiddleware invokes the middleware by decorating the next handler -// provided. Returns the result of the middleware and handler being invoked. -// -// Implements Middleware interface. -func (s *BuildStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( - out interface{}, metadata Metadata, err error, -) { - sIn := BuildInput{ - Request: in, - } - - wh := &buildWrapHandler{next} - if s.head == nil { - res, metadata, err := wh.HandleBuild(ctx, sIn) - return res.Result, metadata, err - } - - s.tail.Next = wh - res, metadata, err := s.head.HandleBuild(ctx, sIn) - return res.Result, metadata, err -} - -// Get retrieves the middleware identified by id. If the middleware is not present, returns false. -func (s *BuildStep) Get(id string) (BuildMiddleware, bool) { - found, _ := s.get(id) - if found == nil { - return nil, false - } - - return found.With, true -} - -// Add injects the middleware to the relative position of the middleware group. -// -// Add never returns an error. It used to for duplicate phases but this -// behavior has since been removed as part of a performance optimization. The -// return value from Add can be ignored. -func (s *BuildStep) Add(m BuildMiddleware, pos RelativePosition) error { - if s.head == nil { - s.head = &decoratedBuildHandler{nil, m} - s.tail = s.head - return nil - } - - if pos == Before { - s.head = &decoratedBuildHandler{s.head, m} - } else { - tail := &decoratedBuildHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } - - return nil -} - -// Insert injects the middleware relative to an existing middleware ID. -// Returns error if the original middleware does not exist, or the middleware -// being added already exists. -func (s *BuildStep) Insert(m BuildMiddleware, relativeTo string, pos RelativePosition) error { - found, prev := s.get(relativeTo) - if found == nil { - return fmt.Errorf("not found: %s", m.ID()) - } - - if pos == Before { - if prev == nil { // at the front - s.head = &decoratedBuildHandler{s.head, m} - } else { // somewhere in the middle - prev.Next = &decoratedBuildHandler{found, m} - } - } else { - if found.Next == nil { // at the end - tail := &decoratedBuildHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } else { // somewhere in the middle - found.Next = &decoratedBuildHandler{found.Next, m} - } - } - - return nil -} - -// Swap removes the middleware by id, replacing it with the new middleware. -// Returns the middleware removed, or error if the middleware to be removed -// doesn't exist. -func (s *BuildStep) Swap(id string, m BuildMiddleware) (BuildMiddleware, error) { - found, _ := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", m.ID()) - } - - swapped := found.With - found.With = m - return swapped, nil -} - -// Remove removes the middleware by id. Returns error if the middleware -// doesn't exist. -func (s *BuildStep) Remove(id string) (BuildMiddleware, error) { - found, prev := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", id) - } - - if s.head == s.tail { // it's the only one - s.head = nil - s.tail = nil - } else if found == s.head { // at the front - s.head = s.head.Next.(*decoratedBuildHandler) - } else if found == s.tail { // at the end - prev.Next = nil - s.tail = prev - } else { - prev.Next = found.Next // somewhere in the middle - } - - return found.With, nil -} - -// List returns a list of the middleware in the step. -func (s *BuildStep) List() []string { - var ids []string - for h := s.head; h != nil; { - ids = append(ids, h.With.ID()) - if h.Next == nil { - break - } - - // once executed, tail.Next of the list will be set to an - // *buildWrapHandler, make sure to check for that - if hnext, ok := h.Next.(*decoratedBuildHandler); ok { - h = hnext - } else { - break - } - } - return ids -} - -// Clear removes all middleware in the step. -func (s *BuildStep) Clear() { - s.head = nil - s.tail = nil -} - -func (s *BuildStep) get(id string) (found, prev *decoratedBuildHandler) { - for h := s.head; h != nil; { - if h.With.ID() == id { - found = h - return - } - prev = h - if h.Next == nil { - return - } - - // once executed, tail.Next of the list will be set to an - // *buildWrapHandler - h, _ = h.Next.(*decoratedBuildHandler) - } - return -} - -type buildWrapHandler struct { - Next Handler -} - -var _ BuildHandler = (*buildWrapHandler)(nil) - -// HandleBuild implements BuildHandler, converts types and delegates to underlying -// generic handler. -func (w buildWrapHandler) HandleBuild(ctx context.Context, in BuildInput) ( - out BuildOutput, metadata Metadata, err error, -) { - res, metadata, err := w.Next.Handle(ctx, in.Request) - return BuildOutput{ - Result: res, - }, metadata, err -} - -type decoratedBuildHandler struct { - Next BuildHandler - With BuildMiddleware -} - -var _ BuildHandler = (*decoratedBuildHandler)(nil) - -func (h decoratedBuildHandler) HandleBuild(ctx context.Context, in BuildInput) ( - out BuildOutput, metadata Metadata, err error, -) { - return h.With.HandleBuild(ctx, in, h.Next) -} - -// BuildHandlerFunc provides a wrapper around a function to be used as buildMiddleware. -type BuildHandlerFunc func(context.Context, BuildInput) (BuildOutput, Metadata, error) - -// HandleBuild calls the wrapped function with the provided arguments. -func (f BuildHandlerFunc) HandleBuild(ctx context.Context, in BuildInput) (BuildOutput, Metadata, error) { - return f(ctx, in) -} - -var _ BuildHandler = BuildHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go b/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go deleted file mode 100644 index 1f337f2..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go +++ /dev/null @@ -1,300 +0,0 @@ -// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. -package middleware - -import ( - "context" - "fmt" -) - -// DeserializeInput provides the input parameters for the DeserializeInput to -// consume. DeserializeMiddleware should not modify the Request, and instead -// forward it along to the next DeserializeHandler. -type DeserializeInput struct { - Request interface{} -} - -// DeserializeOutput provides the result returned by the next DeserializeHandler. -type DeserializeOutput struct { - RawResponse interface{} - Result interface{} -} - -// DeserializeHandler provides the interface for the next handler the -// DeserializeMiddleware will call in the middleware chain. -type DeserializeHandler interface { - HandleDeserialize(ctx context.Context, in DeserializeInput) ( - out DeserializeOutput, metadata Metadata, err error, - ) -} - -// DeserializeMiddleware provides the interface for middleware specific to the -// deserialize step. Delegates to the next DeserializeHandler for further -// processing. -type DeserializeMiddleware interface { - // ID returns a unique ID for the middleware in the DeserializeStep. The step does not - // allow duplicate IDs. - ID() string - - // HandleDeserialize invokes the middleware behavior which must delegate to the next handler - // for the middleware chain to continue. The method must return a result or - // error to its caller. - HandleDeserialize(ctx context.Context, in DeserializeInput, next DeserializeHandler) ( - out DeserializeOutput, metadata Metadata, err error, - ) -} - -// DeserializeMiddlewareFunc returns a DeserializeMiddleware with the unique ID provided, -// and the func to be invoked. -func DeserializeMiddlewareFunc(id string, fn func(context.Context, DeserializeInput, DeserializeHandler) (DeserializeOutput, Metadata, error)) DeserializeMiddleware { - return deserializeMiddlewareFunc{ - id: id, - fn: fn, - } -} - -type deserializeMiddlewareFunc struct { - // Unique ID for the middleware. - id string - - // Middleware function to be called. - fn func(context.Context, DeserializeInput, DeserializeHandler) ( - DeserializeOutput, Metadata, error, - ) -} - -// ID returns the unique ID for the middleware. -func (s deserializeMiddlewareFunc) ID() string { return s.id } - -// HandleDeserialize invokes the middleware Fn. -func (s deserializeMiddlewareFunc) HandleDeserialize(ctx context.Context, in DeserializeInput, next DeserializeHandler) ( - out DeserializeOutput, metadata Metadata, err error, -) { - return s.fn(ctx, in, next) -} - -var _ DeserializeMiddleware = (deserializeMiddlewareFunc{}) - -// DeserializeStep provides the ordered grouping of DeserializeMiddleware to be -// invoked on a handler. -type DeserializeStep struct { - head *decoratedDeserializeHandler - tail *decoratedDeserializeHandler -} - -// NewDeserializeStep returns an DeserializeStep ready to have middleware for -// deserialize added to it. -func NewDeserializeStep() *DeserializeStep { - return &DeserializeStep{} -} - -var _ Middleware = (*DeserializeStep)(nil) - -// ID returns the unique ID of the step as a middleware. -func (s *DeserializeStep) ID() string { - return "Deserialize stack step" -} - -// HandleMiddleware invokes the middleware by decorating the next handler -// provided. Returns the result of the middleware and handler being invoked. -// -// Implements Middleware interface. -func (s *DeserializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( - out interface{}, metadata Metadata, err error, -) { - sIn := DeserializeInput{ - Request: in, - } - - wh := &deserializeWrapHandler{next} - if s.head == nil { - res, metadata, err := wh.HandleDeserialize(ctx, sIn) - return res.Result, metadata, err - } - - s.tail.Next = wh - res, metadata, err := s.head.HandleDeserialize(ctx, sIn) - return res.Result, metadata, err -} - -// Get retrieves the middleware identified by id. If the middleware is not present, returns false. -func (s *DeserializeStep) Get(id string) (DeserializeMiddleware, bool) { - found, _ := s.get(id) - if found == nil { - return nil, false - } - - return found.With, true -} - -// Add injects the middleware to the relative position of the middleware group. -// -// Add never returns an error. It used to for duplicate phases but this -// behavior has since been removed as part of a performance optimization. The -// return value from Add can be ignored. -func (s *DeserializeStep) Add(m DeserializeMiddleware, pos RelativePosition) error { - if s.head == nil { - s.head = &decoratedDeserializeHandler{nil, m} - s.tail = s.head - return nil - } - - if pos == Before { - s.head = &decoratedDeserializeHandler{s.head, m} - } else { - tail := &decoratedDeserializeHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } - - return nil -} - -// Insert injects the middleware relative to an existing middleware ID. -// Returns error if the original middleware does not exist, or the middleware -// being added already exists. -func (s *DeserializeStep) Insert(m DeserializeMiddleware, relativeTo string, pos RelativePosition) error { - found, prev := s.get(relativeTo) - if found == nil { - return fmt.Errorf("not found: %s", m.ID()) - } - - if pos == Before { - if prev == nil { // at the front - s.head = &decoratedDeserializeHandler{s.head, m} - } else { // somewhere in the middle - prev.Next = &decoratedDeserializeHandler{found, m} - } - } else { - if found.Next == nil { // at the end - tail := &decoratedDeserializeHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } else { // somewhere in the middle - found.Next = &decoratedDeserializeHandler{found.Next, m} - } - } - - return nil -} - -// Swap removes the middleware by id, replacing it with the new middleware. -// Returns the middleware removed, or error if the middleware to be removed -// doesn't exist. -func (s *DeserializeStep) Swap(id string, m DeserializeMiddleware) (DeserializeMiddleware, error) { - found, _ := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", m.ID()) - } - - swapped := found.With - found.With = m - return swapped, nil -} - -// Remove removes the middleware by id. Returns error if the middleware -// doesn't exist. -func (s *DeserializeStep) Remove(id string) (DeserializeMiddleware, error) { - found, prev := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", id) - } - - if s.head == s.tail { // it's the only one - s.head = nil - s.tail = nil - } else if found == s.head { // at the front - s.head = s.head.Next.(*decoratedDeserializeHandler) - } else if found == s.tail { // at the end - prev.Next = nil - s.tail = prev - } else { - prev.Next = found.Next // somewhere in the middle - } - - return found.With, nil -} - -// List returns a list of the middleware in the step. -func (s *DeserializeStep) List() []string { - var ids []string - for h := s.head; h != nil; { - ids = append(ids, h.With.ID()) - if h.Next == nil { - break - } - - // once executed, tail.Next of the list will be set to an - // *deserializeWrapHandler, make sure to check for that - if hnext, ok := h.Next.(*decoratedDeserializeHandler); ok { - h = hnext - } else { - break - } - } - return ids -} - -// Clear removes all middleware in the step. -func (s *DeserializeStep) Clear() { - s.head = nil - s.tail = nil -} - -func (s *DeserializeStep) get(id string) (found, prev *decoratedDeserializeHandler) { - for h := s.head; h != nil; { - if h.With.ID() == id { - found = h - return - } - prev = h - if h.Next == nil { - return - } - - // once executed, tail.Next of the list will be set to an - // *deserializeWrapHandler - h, _ = h.Next.(*decoratedDeserializeHandler) - } - return -} - -type deserializeWrapHandler struct { - Next Handler -} - -var _ DeserializeHandler = (*deserializeWrapHandler)(nil) - -// HandleDeserialize implements DeserializeHandler, converts types and delegates to underlying -// generic handler. -func (w deserializeWrapHandler) HandleDeserialize(ctx context.Context, in DeserializeInput) ( - out DeserializeOutput, metadata Metadata, err error, -) { - res, metadata, err := w.Next.Handle(ctx, in.Request) - return DeserializeOutput{ - RawResponse: res, - Result: nil, - }, metadata, err -} - -type decoratedDeserializeHandler struct { - Next DeserializeHandler - With DeserializeMiddleware -} - -var _ DeserializeHandler = (*decoratedDeserializeHandler)(nil) - -func (h decoratedDeserializeHandler) HandleDeserialize(ctx context.Context, in DeserializeInput) ( - out DeserializeOutput, metadata Metadata, err error, -) { - return h.With.HandleDeserialize(ctx, in, h.Next) -} - -// DeserializeHandlerFunc provides a wrapper around a function to be used as deserializeMiddleware. -type DeserializeHandlerFunc func(context.Context, DeserializeInput) (DeserializeOutput, Metadata, error) - -// HandleDeserialize calls the wrapped function with the provided arguments. -func (f DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) { - return f(ctx, in) -} - -var _ DeserializeHandler = DeserializeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_finalize.go b/vendor/github.com/aws/smithy-go/middleware/step_finalize.go deleted file mode 100644 index 1a0ad9f..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/step_finalize.go +++ /dev/null @@ -1,298 +0,0 @@ -// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. -package middleware - -import ( - "context" - "fmt" -) - -// FinalizeInput provides the input parameters for the FinalizeMiddleware to -// consume. FinalizeMiddleware may modify the Request value before forwarding -// the FinalizeInput along to the next next FinalizeHandler. -type FinalizeInput struct { - Request interface{} -} - -// FinalizeOutput provides the result returned by the next FinalizeHandler. -type FinalizeOutput struct { - Result interface{} -} - -// FinalizeHandler provides the interface for the next handler the -// FinalizeMiddleware will call in the middleware chain. -type FinalizeHandler interface { - HandleFinalize(ctx context.Context, in FinalizeInput) ( - out FinalizeOutput, metadata Metadata, err error, - ) -} - -// FinalizeMiddleware provides the interface for middleware specific to the -// finalize step. Delegates to the next FinalizeHandler for further -// processing. -type FinalizeMiddleware interface { - // ID returns a unique ID for the middleware in the FinalizeStep. The step does not - // allow duplicate IDs. - ID() string - - // HandleFinalize invokes the middleware behavior which must delegate to the next handler - // for the middleware chain to continue. The method must return a result or - // error to its caller. - HandleFinalize(ctx context.Context, in FinalizeInput, next FinalizeHandler) ( - out FinalizeOutput, metadata Metadata, err error, - ) -} - -// FinalizeMiddlewareFunc returns a FinalizeMiddleware with the unique ID provided, -// and the func to be invoked. -func FinalizeMiddlewareFunc(id string, fn func(context.Context, FinalizeInput, FinalizeHandler) (FinalizeOutput, Metadata, error)) FinalizeMiddleware { - return finalizeMiddlewareFunc{ - id: id, - fn: fn, - } -} - -type finalizeMiddlewareFunc struct { - // Unique ID for the middleware. - id string - - // Middleware function to be called. - fn func(context.Context, FinalizeInput, FinalizeHandler) ( - FinalizeOutput, Metadata, error, - ) -} - -// ID returns the unique ID for the middleware. -func (s finalizeMiddlewareFunc) ID() string { return s.id } - -// HandleFinalize invokes the middleware Fn. -func (s finalizeMiddlewareFunc) HandleFinalize(ctx context.Context, in FinalizeInput, next FinalizeHandler) ( - out FinalizeOutput, metadata Metadata, err error, -) { - return s.fn(ctx, in, next) -} - -var _ FinalizeMiddleware = (finalizeMiddlewareFunc{}) - -// FinalizeStep provides the ordered grouping of FinalizeMiddleware to be -// invoked on a handler. -type FinalizeStep struct { - head *decoratedFinalizeHandler - tail *decoratedFinalizeHandler -} - -// NewFinalizeStep returns an FinalizeStep ready to have middleware for -// finalize added to it. -func NewFinalizeStep() *FinalizeStep { - return &FinalizeStep{} -} - -var _ Middleware = (*FinalizeStep)(nil) - -// ID returns the unique ID of the step as a middleware. -func (s *FinalizeStep) ID() string { - return "Finalize stack step" -} - -// HandleMiddleware invokes the middleware by decorating the next handler -// provided. Returns the result of the middleware and handler being invoked. -// -// Implements Middleware interface. -func (s *FinalizeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( - out interface{}, metadata Metadata, err error, -) { - sIn := FinalizeInput{ - Request: in, - } - - wh := &finalizeWrapHandler{next} - if s.head == nil { - res, metadata, err := wh.HandleFinalize(ctx, sIn) - return res.Result, metadata, err - } - - s.tail.Next = wh - res, metadata, err := s.head.HandleFinalize(ctx, sIn) - return res.Result, metadata, err -} - -// Get retrieves the middleware identified by id. If the middleware is not present, returns false. -func (s *FinalizeStep) Get(id string) (FinalizeMiddleware, bool) { - found, _ := s.get(id) - if found == nil { - return nil, false - } - - return found.With, true -} - -// Add injects the middleware to the relative position of the middleware group. -// -// Add never returns an error. It used to for duplicate phases but this -// behavior has since been removed as part of a performance optimization. The -// return value from Add can be ignored. -func (s *FinalizeStep) Add(m FinalizeMiddleware, pos RelativePosition) error { - if s.head == nil { - s.head = &decoratedFinalizeHandler{nil, m} - s.tail = s.head - return nil - } - - if pos == Before { - s.head = &decoratedFinalizeHandler{s.head, m} - } else { - tail := &decoratedFinalizeHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } - - return nil -} - -// Insert injects the middleware relative to an existing middleware ID. -// Returns error if the original middleware does not exist, or the middleware -// being added already exists. -func (s *FinalizeStep) Insert(m FinalizeMiddleware, relativeTo string, pos RelativePosition) error { - found, prev := s.get(relativeTo) - if found == nil { - return fmt.Errorf("not found: %s", m.ID()) - } - - if pos == Before { - if prev == nil { // at the front - s.head = &decoratedFinalizeHandler{s.head, m} - } else { // somewhere in the middle - prev.Next = &decoratedFinalizeHandler{found, m} - } - } else { - if found.Next == nil { // at the end - tail := &decoratedFinalizeHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } else { // somewhere in the middle - found.Next = &decoratedFinalizeHandler{found.Next, m} - } - } - - return nil -} - -// Swap removes the middleware by id, replacing it with the new middleware. -// Returns the middleware removed, or error if the middleware to be removed -// doesn't exist. -func (s *FinalizeStep) Swap(id string, m FinalizeMiddleware) (FinalizeMiddleware, error) { - found, _ := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", m.ID()) - } - - swapped := found.With - found.With = m - return swapped, nil -} - -// Remove removes the middleware by id. Returns error if the middleware -// doesn't exist. -func (s *FinalizeStep) Remove(id string) (FinalizeMiddleware, error) { - found, prev := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", id) - } - - if s.head == s.tail { // it's the only one - s.head = nil - s.tail = nil - } else if found == s.head { // at the front - s.head = s.head.Next.(*decoratedFinalizeHandler) - } else if found == s.tail { // at the end - prev.Next = nil - s.tail = prev - } else { - prev.Next = found.Next // somewhere in the middle - } - - return found.With, nil -} - -// List returns a list of the middleware in the step. -func (s *FinalizeStep) List() []string { - var ids []string - for h := s.head; h != nil; { - ids = append(ids, h.With.ID()) - if h.Next == nil { - break - } - - // once executed, tail.Next of the list will be set to an - // *finalizeWrapHandler, make sure to check for that - if hnext, ok := h.Next.(*decoratedFinalizeHandler); ok { - h = hnext - } else { - break - } - } - return ids -} - -// Clear removes all middleware in the step. -func (s *FinalizeStep) Clear() { - s.head = nil - s.tail = nil -} - -func (s *FinalizeStep) get(id string) (found, prev *decoratedFinalizeHandler) { - for h := s.head; h != nil; { - if h.With.ID() == id { - found = h - return - } - prev = h - if h.Next == nil { - return - } - - // once executed, tail.Next of the list will be set to an - // *finalizeWrapHandler - h, _ = h.Next.(*decoratedFinalizeHandler) - } - return -} - -type finalizeWrapHandler struct { - Next Handler -} - -var _ FinalizeHandler = (*finalizeWrapHandler)(nil) - -// HandleFinalize implements FinalizeHandler, converts types and delegates to underlying -// generic handler. -func (w finalizeWrapHandler) HandleFinalize(ctx context.Context, in FinalizeInput) ( - out FinalizeOutput, metadata Metadata, err error, -) { - res, metadata, err := w.Next.Handle(ctx, in.Request) - return FinalizeOutput{ - Result: res, - }, metadata, err -} - -type decoratedFinalizeHandler struct { - Next FinalizeHandler - With FinalizeMiddleware -} - -var _ FinalizeHandler = (*decoratedFinalizeHandler)(nil) - -func (h decoratedFinalizeHandler) HandleFinalize(ctx context.Context, in FinalizeInput) ( - out FinalizeOutput, metadata Metadata, err error, -) { - return h.With.HandleFinalize(ctx, in, h.Next) -} - -// FinalizeHandlerFunc provides a wrapper around a function to be used as finalizeMiddleware. -type FinalizeHandlerFunc func(context.Context, FinalizeInput) (FinalizeOutput, Metadata, error) - -// HandleFinalize calls the wrapped function with the provided arguments. -func (f FinalizeHandlerFunc) HandleFinalize(ctx context.Context, in FinalizeInput) (FinalizeOutput, Metadata, error) { - return f(ctx, in) -} - -var _ FinalizeHandler = FinalizeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_initialize.go b/vendor/github.com/aws/smithy-go/middleware/step_initialize.go deleted file mode 100644 index 446f3b7..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/step_initialize.go +++ /dev/null @@ -1,299 +0,0 @@ -// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. -package middleware - -import ( - "context" - "fmt" -) - -// InitializeInput wraps the input parameters for the InitializeMiddlewares to -// consume. InitializeMiddleware may modify the parameter value before -// forwarding it along to the next InitializeHandler. - -type InitializeInput struct { - Parameters interface{} -} - -// InitializeOutput provides the result returned by the next InitializeHandler. -type InitializeOutput struct { - Result interface{} -} - -// InitializeHandler provides the interface for the next handler the -// InitializeMiddleware will call in the middleware chain. -type InitializeHandler interface { - HandleInitialize(ctx context.Context, in InitializeInput) ( - out InitializeOutput, metadata Metadata, err error, - ) -} - -// InitializeMiddleware provides the interface for middleware specific to the -// initialize step. Delegates to the next InitializeHandler for further -// processing. -type InitializeMiddleware interface { - // ID returns a unique ID for the middleware in the InitializeStep. The step does not - // allow duplicate IDs. - ID() string - - // HandleInitialize invokes the middleware behavior which must delegate to the next handler - // for the middleware chain to continue. The method must return a result or - // error to its caller. - HandleInitialize(ctx context.Context, in InitializeInput, next InitializeHandler) ( - out InitializeOutput, metadata Metadata, err error, - ) -} - -// InitializeMiddlewareFunc returns a InitializeMiddleware with the unique ID provided, -// and the func to be invoked. -func InitializeMiddlewareFunc(id string, fn func(context.Context, InitializeInput, InitializeHandler) (InitializeOutput, Metadata, error)) InitializeMiddleware { - return initializeMiddlewareFunc{ - id: id, - fn: fn, - } -} - -type initializeMiddlewareFunc struct { - // Unique ID for the middleware. - id string - - // Middleware function to be called. - fn func(context.Context, InitializeInput, InitializeHandler) ( - InitializeOutput, Metadata, error, - ) -} - -// ID returns the unique ID for the middleware. -func (s initializeMiddlewareFunc) ID() string { return s.id } - -// HandleInitialize invokes the middleware Fn. -func (s initializeMiddlewareFunc) HandleInitialize(ctx context.Context, in InitializeInput, next InitializeHandler) ( - out InitializeOutput, metadata Metadata, err error, -) { - return s.fn(ctx, in, next) -} - -var _ InitializeMiddleware = (initializeMiddlewareFunc{}) - -// InitializeStep provides the ordered grouping of InitializeMiddleware to be -// invoked on a handler. -type InitializeStep struct { - head *decoratedInitializeHandler - tail *decoratedInitializeHandler -} - -// NewInitializeStep returns an InitializeStep ready to have middleware for -// initialize added to it. -func NewInitializeStep() *InitializeStep { - return &InitializeStep{} -} - -var _ Middleware = (*InitializeStep)(nil) - -// ID returns the unique ID of the step as a middleware. -func (s *InitializeStep) ID() string { - return "Initialize stack step" -} - -// HandleMiddleware invokes the middleware by decorating the next handler -// provided. Returns the result of the middleware and handler being invoked. -// -// Implements Middleware interface. -func (s *InitializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( - out interface{}, metadata Metadata, err error, -) { - sIn := InitializeInput{ - Parameters: in, - } - - wh := &initializeWrapHandler{next} - if s.head == nil { - res, metadata, err := wh.HandleInitialize(ctx, sIn) - return res.Result, metadata, err - } - - s.tail.Next = wh - res, metadata, err := s.head.HandleInitialize(ctx, sIn) - return res.Result, metadata, err -} - -// Get retrieves the middleware identified by id. If the middleware is not present, returns false. -func (s *InitializeStep) Get(id string) (InitializeMiddleware, bool) { - found, _ := s.get(id) - if found == nil { - return nil, false - } - - return found.With, true -} - -// Add injects the middleware to the relative position of the middleware group. -// -// Add never returns an error. It used to for duplicate phases but this -// behavior has since been removed as part of a performance optimization. The -// return value from Add can be ignored. -func (s *InitializeStep) Add(m InitializeMiddleware, pos RelativePosition) error { - if s.head == nil { - s.head = &decoratedInitializeHandler{nil, m} - s.tail = s.head - return nil - } - - if pos == Before { - s.head = &decoratedInitializeHandler{s.head, m} - } else { - tail := &decoratedInitializeHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } - - return nil -} - -// Insert injects the middleware relative to an existing middleware ID. -// Returns error if the original middleware does not exist, or the middleware -// being added already exists. -func (s *InitializeStep) Insert(m InitializeMiddleware, relativeTo string, pos RelativePosition) error { - found, prev := s.get(relativeTo) - if found == nil { - return fmt.Errorf("not found: %s", m.ID()) - } - - if pos == Before { - if prev == nil { // at the front - s.head = &decoratedInitializeHandler{s.head, m} - } else { // somewhere in the middle - prev.Next = &decoratedInitializeHandler{found, m} - } - } else { - if found.Next == nil { // at the end - tail := &decoratedInitializeHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } else { // somewhere in the middle - found.Next = &decoratedInitializeHandler{found.Next, m} - } - } - - return nil -} - -// Swap removes the middleware by id, replacing it with the new middleware. -// Returns the middleware removed, or error if the middleware to be removed -// doesn't exist. -func (s *InitializeStep) Swap(id string, m InitializeMiddleware) (InitializeMiddleware, error) { - found, _ := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", m.ID()) - } - - swapped := found.With - found.With = m - return swapped, nil -} - -// Remove removes the middleware by id. Returns error if the middleware -// doesn't exist. -func (s *InitializeStep) Remove(id string) (InitializeMiddleware, error) { - found, prev := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", id) - } - - if s.head == s.tail { // it's the only one - s.head = nil - s.tail = nil - } else if found == s.head { // at the front - s.head = s.head.Next.(*decoratedInitializeHandler) - } else if found == s.tail { // at the end - prev.Next = nil - s.tail = prev - } else { - prev.Next = found.Next // somewhere in the middle - } - - return found.With, nil -} - -// List returns a list of the middleware in the step. -func (s *InitializeStep) List() []string { - var ids []string - for h := s.head; h != nil; { - ids = append(ids, h.With.ID()) - if h.Next == nil { - break - } - - // once executed, tail.Next of the list will be set to an - // *initializeWrapHandler, make sure to check for that - if hnext, ok := h.Next.(*decoratedInitializeHandler); ok { - h = hnext - } else { - break - } - } - return ids -} - -// Clear removes all middleware in the step. -func (s *InitializeStep) Clear() { - s.head = nil - s.tail = nil -} - -func (s *InitializeStep) get(id string) (found, prev *decoratedInitializeHandler) { - for h := s.head; h != nil; { - if h.With.ID() == id { - found = h - return - } - prev = h - if h.Next == nil { - return - } - - // once executed, tail.Next of the list will be set to an - // *initializeWrapHandler - h, _ = h.Next.(*decoratedInitializeHandler) - } - return -} - -type initializeWrapHandler struct { - Next Handler -} - -var _ InitializeHandler = (*initializeWrapHandler)(nil) - -// HandleInitialize implements InitializeHandler, converts types and delegates to underlying -// generic handler. -func (w initializeWrapHandler) HandleInitialize(ctx context.Context, in InitializeInput) ( - out InitializeOutput, metadata Metadata, err error, -) { - res, metadata, err := w.Next.Handle(ctx, in.Parameters) - return InitializeOutput{ - Result: res, - }, metadata, err -} - -type decoratedInitializeHandler struct { - Next InitializeHandler - With InitializeMiddleware -} - -var _ InitializeHandler = (*decoratedInitializeHandler)(nil) - -func (h decoratedInitializeHandler) HandleInitialize(ctx context.Context, in InitializeInput) ( - out InitializeOutput, metadata Metadata, err error, -) { - return h.With.HandleInitialize(ctx, in, h.Next) -} - -// InitializeHandlerFunc provides a wrapper around a function to be used as initializeMiddleware. -type InitializeHandlerFunc func(context.Context, InitializeInput) (InitializeOutput, Metadata, error) - -// HandleInitialize calls the wrapped function with the provided arguments. -func (f InitializeHandlerFunc) HandleInitialize(ctx context.Context, in InitializeInput) (InitializeOutput, Metadata, error) { - return f(ctx, in) -} - -var _ InitializeHandler = InitializeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_serialize.go b/vendor/github.com/aws/smithy-go/middleware/step_serialize.go deleted file mode 100644 index 942ebb4..0000000 --- a/vendor/github.com/aws/smithy-go/middleware/step_serialize.go +++ /dev/null @@ -1,305 +0,0 @@ -// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. -package middleware - -import ( - "context" - "fmt" -) - -// SerializeInput provides the input parameters for the SerializeMiddleware to -// consume. SerializeMiddleware may modify the Request value before forwarding -// SerializeInput along to the next SerializeHandler. The Parameters member -// should not be modified by SerializeMiddleware, InitializeMiddleware should -// be responsible for modifying the provided Parameter value. -type SerializeInput struct { - Parameters interface{} - Request interface{} -} - -// SerializeOutput provides the result returned by the next SerializeHandler. -type SerializeOutput struct { - Result interface{} -} - -// SerializeHandler provides the interface for the next handler the -// SerializeMiddleware will call in the middleware chain. -type SerializeHandler interface { - HandleSerialize(ctx context.Context, in SerializeInput) ( - out SerializeOutput, metadata Metadata, err error, - ) -} - -// SerializeMiddleware provides the interface for middleware specific to the -// serialize step. Delegates to the next SerializeHandler for further -// processing. -type SerializeMiddleware interface { - // ID returns a unique ID for the middleware in the SerializeStep. The step does not - // allow duplicate IDs. - ID() string - - // HandleSerialize invokes the middleware behavior which must delegate to the next handler - // for the middleware chain to continue. The method must return a result or - // error to its caller. - HandleSerialize(ctx context.Context, in SerializeInput, next SerializeHandler) ( - out SerializeOutput, metadata Metadata, err error, - ) -} - -// SerializeMiddlewareFunc returns a SerializeMiddleware with the unique ID provided, -// and the func to be invoked. -func SerializeMiddlewareFunc(id string, fn func(context.Context, SerializeInput, SerializeHandler) (SerializeOutput, Metadata, error)) SerializeMiddleware { - return serializeMiddlewareFunc{ - id: id, - fn: fn, - } -} - -type serializeMiddlewareFunc struct { - // Unique ID for the middleware. - id string - - // Middleware function to be called. - fn func(context.Context, SerializeInput, SerializeHandler) ( - SerializeOutput, Metadata, error, - ) -} - -// ID returns the unique ID for the middleware. -func (s serializeMiddlewareFunc) ID() string { return s.id } - -// HandleSerialize invokes the middleware Fn. -func (s serializeMiddlewareFunc) HandleSerialize(ctx context.Context, in SerializeInput, next SerializeHandler) ( - out SerializeOutput, metadata Metadata, err error, -) { - return s.fn(ctx, in, next) -} - -var _ SerializeMiddleware = (serializeMiddlewareFunc{}) - -// SerializeStep provides the ordered grouping of SerializeMiddleware to be -// invoked on a handler. -type SerializeStep struct { - head *decoratedSerializeHandler - tail *decoratedSerializeHandler - newRequest func() interface{} -} - -// NewSerializeStep returns an SerializeStep ready to have middleware for -// serialize added to it. -func NewSerializeStep(newRequest func() interface{}) *SerializeStep { - return &SerializeStep{ - newRequest: newRequest, - } -} - -var _ Middleware = (*SerializeStep)(nil) - -// ID returns the unique ID of the step as a middleware. -func (s *SerializeStep) ID() string { - return "Serialize stack step" -} - -// HandleMiddleware invokes the middleware by decorating the next handler -// provided. Returns the result of the middleware and handler being invoked. -// -// Implements Middleware interface. -func (s *SerializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( - out interface{}, metadata Metadata, err error, -) { - sIn := SerializeInput{ - Parameters: in, - Request: s.newRequest(), - } - - wh := &serializeWrapHandler{next} - if s.head == nil { - res, metadata, err := wh.HandleSerialize(ctx, sIn) - return res.Result, metadata, err - } - - s.tail.Next = wh - res, metadata, err := s.head.HandleSerialize(ctx, sIn) - return res.Result, metadata, err -} - -// Get retrieves the middleware identified by id. If the middleware is not present, returns false. -func (s *SerializeStep) Get(id string) (SerializeMiddleware, bool) { - found, _ := s.get(id) - if found == nil { - return nil, false - } - - return found.With, true -} - -// Add injects the middleware to the relative position of the middleware group. -// -// Add never returns an error. It used to for duplicate phases but this -// behavior has since been removed as part of a performance optimization. The -// return value from Add can be ignored. -func (s *SerializeStep) Add(m SerializeMiddleware, pos RelativePosition) error { - if s.head == nil { - s.head = &decoratedSerializeHandler{nil, m} - s.tail = s.head - return nil - } - - if pos == Before { - s.head = &decoratedSerializeHandler{s.head, m} - } else { - tail := &decoratedSerializeHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } - - return nil -} - -// Insert injects the middleware relative to an existing middleware ID. -// Returns error if the original middleware does not exist, or the middleware -// being added already exists. -func (s *SerializeStep) Insert(m SerializeMiddleware, relativeTo string, pos RelativePosition) error { - found, prev := s.get(relativeTo) - if found == nil { - return fmt.Errorf("not found: %s", m.ID()) - } - - if pos == Before { - if prev == nil { // at the front - s.head = &decoratedSerializeHandler{s.head, m} - } else { // somewhere in the middle - prev.Next = &decoratedSerializeHandler{found, m} - } - } else { - if found.Next == nil { // at the end - tail := &decoratedSerializeHandler{nil, m} - s.tail.Next = tail - s.tail = tail - } else { // somewhere in the middle - found.Next = &decoratedSerializeHandler{found.Next, m} - } - } - - return nil -} - -// Swap removes the middleware by id, replacing it with the new middleware. -// Returns the middleware removed, or error if the middleware to be removed -// doesn't exist. -func (s *SerializeStep) Swap(id string, m SerializeMiddleware) (SerializeMiddleware, error) { - found, _ := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", m.ID()) - } - - swapped := found.With - found.With = m - return swapped, nil -} - -// Remove removes the middleware by id. Returns error if the middleware -// doesn't exist. -func (s *SerializeStep) Remove(id string) (SerializeMiddleware, error) { - found, prev := s.get(id) - if found == nil { - return nil, fmt.Errorf("not found: %s", id) - } - - if s.head == s.tail { // it's the only one - s.head = nil - s.tail = nil - } else if found == s.head { // at the front - s.head = s.head.Next.(*decoratedSerializeHandler) - } else if found == s.tail { // at the end - prev.Next = nil - s.tail = prev - } else { - prev.Next = found.Next // somewhere in the middle - } - - return found.With, nil -} - -// List returns a list of the middleware in the step. -func (s *SerializeStep) List() []string { - var ids []string - for h := s.head; h != nil; { - ids = append(ids, h.With.ID()) - if h.Next == nil { - break - } - - // once executed, tail.Next of the list will be set to an - // *serializeWrapHandler, make sure to check for that - if hnext, ok := h.Next.(*decoratedSerializeHandler); ok { - h = hnext - } else { - break - } - } - return ids -} - -// Clear removes all middleware in the step. -func (s *SerializeStep) Clear() { - s.head = nil - s.tail = nil -} - -func (s *SerializeStep) get(id string) (found, prev *decoratedSerializeHandler) { - for h := s.head; h != nil; { - if h.With.ID() == id { - found = h - return - } - prev = h - if h.Next == nil { - return - } - - // once executed, tail.Next of the list will be set to an - // *serializeWrapHandler - h, _ = h.Next.(*decoratedSerializeHandler) - } - return -} - -type serializeWrapHandler struct { - Next Handler -} - -var _ SerializeHandler = (*serializeWrapHandler)(nil) - -// HandleSerialize implements SerializeHandler, converts types and delegates to underlying -// generic handler. -func (w serializeWrapHandler) HandleSerialize(ctx context.Context, in SerializeInput) ( - out SerializeOutput, metadata Metadata, err error, -) { - res, metadata, err := w.Next.Handle(ctx, in.Request) - return SerializeOutput{ - Result: res, - }, metadata, err -} - -type decoratedSerializeHandler struct { - Next SerializeHandler - With SerializeMiddleware -} - -var _ SerializeHandler = (*decoratedSerializeHandler)(nil) - -func (h decoratedSerializeHandler) HandleSerialize(ctx context.Context, in SerializeInput) ( - out SerializeOutput, metadata Metadata, err error, -) { - return h.With.HandleSerialize(ctx, in, h.Next) -} - -// SerializeHandlerFunc provides a wrapper around a function to be used as serializeMiddleware. -type SerializeHandlerFunc func(context.Context, SerializeInput) (SerializeOutput, Metadata, error) - -// HandleSerialize calls the wrapped function with the provided arguments. -func (f SerializeHandlerFunc) HandleSerialize(ctx context.Context, in SerializeInput) (SerializeOutput, Metadata, error) { - return f(ctx, in) -} - -var _ SerializeHandler = SerializeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/modman.toml b/vendor/github.com/aws/smithy-go/modman.toml deleted file mode 100644 index aac582f..0000000 --- a/vendor/github.com/aws/smithy-go/modman.toml +++ /dev/null @@ -1,9 +0,0 @@ -[dependencies] - -[modules] - - [modules.codegen] - no_tag = true - - [modules."codegen/smithy-go-codegen/build/test-generated/go/internal/testmodule"] - no_tag = true diff --git a/vendor/github.com/aws/smithy-go/private/requestcompression/gzip.go b/vendor/github.com/aws/smithy-go/private/requestcompression/gzip.go deleted file mode 100644 index 004d78f..0000000 --- a/vendor/github.com/aws/smithy-go/private/requestcompression/gzip.go +++ /dev/null @@ -1,30 +0,0 @@ -package requestcompression - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" -) - -func gzipCompress(input io.Reader) ([]byte, error) { - var b bytes.Buffer - w, err := gzip.NewWriterLevel(&b, gzip.DefaultCompression) - if err != nil { - return nil, fmt.Errorf("failed to create gzip writer, %v", err) - } - - inBytes, err := io.ReadAll(input) - if err != nil { - return nil, fmt.Errorf("failed read payload to compress, %v", err) - } - - if _, err = w.Write(inBytes); err != nil { - return nil, fmt.Errorf("failed to write payload to be compressed, %v", err) - } - if err = w.Close(); err != nil { - return nil, fmt.Errorf("failed to flush payload being compressed, %v", err) - } - - return b.Bytes(), nil -} diff --git a/vendor/github.com/aws/smithy-go/private/requestcompression/middleware_capture_request_compression.go b/vendor/github.com/aws/smithy-go/private/requestcompression/middleware_capture_request_compression.go deleted file mode 100644 index 06c16af..0000000 --- a/vendor/github.com/aws/smithy-go/private/requestcompression/middleware_capture_request_compression.go +++ /dev/null @@ -1,52 +0,0 @@ -package requestcompression - -import ( - "bytes" - "context" - "fmt" - "github.com/aws/smithy-go/middleware" - smithyhttp "github.com/aws/smithy-go/transport/http" - "io" - "net/http" -) - -const captureUncompressedRequestID = "CaptureUncompressedRequest" - -// AddCaptureUncompressedRequestMiddleware captures http request before compress encoding for check -func AddCaptureUncompressedRequestMiddleware(stack *middleware.Stack, buf *bytes.Buffer) error { - return stack.Serialize.Insert(&captureUncompressedRequestMiddleware{ - buf: buf, - }, "RequestCompression", middleware.Before) -} - -type captureUncompressedRequestMiddleware struct { - req *http.Request - buf *bytes.Buffer - bytes []byte -} - -// ID returns id of the captureUncompressedRequestMiddleware -func (*captureUncompressedRequestMiddleware) ID() string { - return captureUncompressedRequestID -} - -// HandleSerialize captures request payload before it is compressed by request compression middleware -func (m *captureUncompressedRequestMiddleware) HandleSerialize(ctx context.Context, input middleware.SerializeInput, next middleware.SerializeHandler, -) ( - output middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - request, ok := input.Request.(*smithyhttp.Request) - if !ok { - return output, metadata, fmt.Errorf("error when retrieving http request") - } - - _, err = io.Copy(m.buf, request.GetStream()) - if err != nil { - return output, metadata, fmt.Errorf("error when copying http request stream: %q", err) - } - if err = request.RewindStream(); err != nil { - return output, metadata, fmt.Errorf("error when rewinding request stream: %q", err) - } - - return next.HandleSerialize(ctx, input) -} diff --git a/vendor/github.com/aws/smithy-go/private/requestcompression/request_compression.go b/vendor/github.com/aws/smithy-go/private/requestcompression/request_compression.go deleted file mode 100644 index 7c41476..0000000 --- a/vendor/github.com/aws/smithy-go/private/requestcompression/request_compression.go +++ /dev/null @@ -1,103 +0,0 @@ -// Package requestcompression implements runtime support for smithy-modeled -// request compression. -// -// This package is designated as private and is intended for use only by the -// smithy client runtime. The exported API therein is not considered stable and -// is subject to breaking changes without notice. -package requestcompression - -import ( - "bytes" - "context" - "fmt" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/transport/http" - "io" -) - -const MaxRequestMinCompressSizeBytes = 10485760 - -// Enumeration values for supported compress Algorithms. -const ( - GZIP = "gzip" -) - -type compressFunc func(io.Reader) ([]byte, error) - -var allowedAlgorithms = map[string]compressFunc{ - GZIP: gzipCompress, -} - -// AddRequestCompression add requestCompression middleware to op stack -func AddRequestCompression(stack *middleware.Stack, disabled bool, minBytes int64, algorithms []string) error { - return stack.Serialize.Add(&requestCompression{ - disableRequestCompression: disabled, - requestMinCompressSizeBytes: minBytes, - compressAlgorithms: algorithms, - }, middleware.After) -} - -type requestCompression struct { - disableRequestCompression bool - requestMinCompressSizeBytes int64 - compressAlgorithms []string -} - -// ID returns the ID of the middleware -func (m requestCompression) ID() string { - return "RequestCompression" -} - -// HandleSerialize gzip compress the request's stream/body if enabled by config fields -func (m requestCompression) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - out middleware.SerializeOutput, metadata middleware.Metadata, err error, -) { - if m.disableRequestCompression { - return next.HandleSerialize(ctx, in) - } - // still need to check requestMinCompressSizeBytes in case it is out of range after service client config - if m.requestMinCompressSizeBytes < 0 || m.requestMinCompressSizeBytes > MaxRequestMinCompressSizeBytes { - return out, metadata, fmt.Errorf("invalid range for min request compression size bytes %d, must be within 0 and 10485760 inclusively", m.requestMinCompressSizeBytes) - } - - req, ok := in.Request.(*http.Request) - if !ok { - return out, metadata, fmt.Errorf("unknown request type %T", req) - } - - for _, algorithm := range m.compressAlgorithms { - compressFunc := allowedAlgorithms[algorithm] - if compressFunc != nil { - if stream := req.GetStream(); stream != nil { - size, found, err := req.StreamLength() - if err != nil { - return out, metadata, fmt.Errorf("error while finding request stream length, %v", err) - } else if !found || size < m.requestMinCompressSizeBytes { - return next.HandleSerialize(ctx, in) - } - - compressedBytes, err := compressFunc(stream) - if err != nil { - return out, metadata, fmt.Errorf("failed to compress request stream, %v", err) - } - - var newReq *http.Request - if newReq, err = req.SetStream(bytes.NewReader(compressedBytes)); err != nil { - return out, metadata, fmt.Errorf("failed to set request stream, %v", err) - } - *req = *newReq - - if val := req.Header.Get("Content-Encoding"); val != "" { - req.Header.Set("Content-Encoding", fmt.Sprintf("%s, %s", val, algorithm)) - } else { - req.Header.Set("Content-Encoding", algorithm) - } - } - break - } - } - - return next.HandleSerialize(ctx, in) -} diff --git a/vendor/github.com/aws/smithy-go/properties.go b/vendor/github.com/aws/smithy-go/properties.go deleted file mode 100644 index 68df4c4..0000000 --- a/vendor/github.com/aws/smithy-go/properties.go +++ /dev/null @@ -1,69 +0,0 @@ -package smithy - -import "maps" - -// PropertiesReader provides an interface for reading metadata from the -// underlying metadata container. -type PropertiesReader interface { - Get(key any) any -} - -// Properties provides storing and reading metadata values. Keys may be any -// comparable value type. Get and Set will panic if a key is not comparable. -// -// The zero value for a Properties instance is ready for reads/writes without -// any additional initialization. -type Properties struct { - values map[any]any -} - -// Get attempts to retrieve the value the key points to. Returns nil if the -// key was not found. -// -// Panics if key type is not comparable. -func (m *Properties) Get(key any) any { - m.lazyInit() - return m.values[key] -} - -// Set stores the value pointed to by the key. If a value already exists at -// that key it will be replaced with the new value. -// -// Panics if the key type is not comparable. -func (m *Properties) Set(key, value any) { - m.lazyInit() - m.values[key] = value -} - -// Has returns whether the key exists in the metadata. -// -// Panics if the key type is not comparable. -func (m *Properties) Has(key any) bool { - m.lazyInit() - _, ok := m.values[key] - return ok -} - -// SetAll accepts all of the given Properties into the receiver, overwriting -// any existing keys in the case of conflicts. -func (m *Properties) SetAll(other *Properties) { - if other.values == nil { - return - } - - m.lazyInit() - for k, v := range other.values { - m.values[k] = v - } -} - -// Values returns a shallow clone of the property set's values. -func (m *Properties) Values() map[any]any { - return maps.Clone(m.values) -} - -func (m *Properties) lazyInit() { - if m.values == nil { - m.values = map[any]any{} - } -} diff --git a/vendor/github.com/aws/smithy-go/ptr/doc.go b/vendor/github.com/aws/smithy-go/ptr/doc.go deleted file mode 100644 index bc1f699..0000000 --- a/vendor/github.com/aws/smithy-go/ptr/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -// Package ptr provides utilities for converting scalar literal type values to and from pointers inline. -package ptr - -//go:generate go run -tags codegen generate.go -//go:generate gofmt -w -s . diff --git a/vendor/github.com/aws/smithy-go/ptr/from_ptr.go b/vendor/github.com/aws/smithy-go/ptr/from_ptr.go deleted file mode 100644 index a2845bb..0000000 --- a/vendor/github.com/aws/smithy-go/ptr/from_ptr.go +++ /dev/null @@ -1,601 +0,0 @@ -// Code generated by smithy-go/ptr/generate.go DO NOT EDIT. -package ptr - -import ( - "time" -) - -// ToBool returns bool value dereferenced if the passed -// in pointer was not nil. Returns a bool zero value if the -// pointer was nil. -func ToBool(p *bool) (v bool) { - if p == nil { - return v - } - - return *p -} - -// ToBoolSlice returns a slice of bool values, that are -// dereferenced if the passed in pointer was not nil. Returns a bool -// zero value if the pointer was nil. -func ToBoolSlice(vs []*bool) []bool { - ps := make([]bool, len(vs)) - for i, v := range vs { - ps[i] = ToBool(v) - } - - return ps -} - -// ToBoolMap returns a map of bool values, that are -// dereferenced if the passed in pointer was not nil. The bool -// zero value is used if the pointer was nil. -func ToBoolMap(vs map[string]*bool) map[string]bool { - ps := make(map[string]bool, len(vs)) - for k, v := range vs { - ps[k] = ToBool(v) - } - - return ps -} - -// ToByte returns byte value dereferenced if the passed -// in pointer was not nil. Returns a byte zero value if the -// pointer was nil. -func ToByte(p *byte) (v byte) { - if p == nil { - return v - } - - return *p -} - -// ToByteSlice returns a slice of byte values, that are -// dereferenced if the passed in pointer was not nil. Returns a byte -// zero value if the pointer was nil. -func ToByteSlice(vs []*byte) []byte { - ps := make([]byte, len(vs)) - for i, v := range vs { - ps[i] = ToByte(v) - } - - return ps -} - -// ToByteMap returns a map of byte values, that are -// dereferenced if the passed in pointer was not nil. The byte -// zero value is used if the pointer was nil. -func ToByteMap(vs map[string]*byte) map[string]byte { - ps := make(map[string]byte, len(vs)) - for k, v := range vs { - ps[k] = ToByte(v) - } - - return ps -} - -// ToString returns string value dereferenced if the passed -// in pointer was not nil. Returns a string zero value if the -// pointer was nil. -func ToString(p *string) (v string) { - if p == nil { - return v - } - - return *p -} - -// ToStringSlice returns a slice of string values, that are -// dereferenced if the passed in pointer was not nil. Returns a string -// zero value if the pointer was nil. -func ToStringSlice(vs []*string) []string { - ps := make([]string, len(vs)) - for i, v := range vs { - ps[i] = ToString(v) - } - - return ps -} - -// ToStringMap returns a map of string values, that are -// dereferenced if the passed in pointer was not nil. The string -// zero value is used if the pointer was nil. -func ToStringMap(vs map[string]*string) map[string]string { - ps := make(map[string]string, len(vs)) - for k, v := range vs { - ps[k] = ToString(v) - } - - return ps -} - -// ToInt returns int value dereferenced if the passed -// in pointer was not nil. Returns a int zero value if the -// pointer was nil. -func ToInt(p *int) (v int) { - if p == nil { - return v - } - - return *p -} - -// ToIntSlice returns a slice of int values, that are -// dereferenced if the passed in pointer was not nil. Returns a int -// zero value if the pointer was nil. -func ToIntSlice(vs []*int) []int { - ps := make([]int, len(vs)) - for i, v := range vs { - ps[i] = ToInt(v) - } - - return ps -} - -// ToIntMap returns a map of int values, that are -// dereferenced if the passed in pointer was not nil. The int -// zero value is used if the pointer was nil. -func ToIntMap(vs map[string]*int) map[string]int { - ps := make(map[string]int, len(vs)) - for k, v := range vs { - ps[k] = ToInt(v) - } - - return ps -} - -// ToInt8 returns int8 value dereferenced if the passed -// in pointer was not nil. Returns a int8 zero value if the -// pointer was nil. -func ToInt8(p *int8) (v int8) { - if p == nil { - return v - } - - return *p -} - -// ToInt8Slice returns a slice of int8 values, that are -// dereferenced if the passed in pointer was not nil. Returns a int8 -// zero value if the pointer was nil. -func ToInt8Slice(vs []*int8) []int8 { - ps := make([]int8, len(vs)) - for i, v := range vs { - ps[i] = ToInt8(v) - } - - return ps -} - -// ToInt8Map returns a map of int8 values, that are -// dereferenced if the passed in pointer was not nil. The int8 -// zero value is used if the pointer was nil. -func ToInt8Map(vs map[string]*int8) map[string]int8 { - ps := make(map[string]int8, len(vs)) - for k, v := range vs { - ps[k] = ToInt8(v) - } - - return ps -} - -// ToInt16 returns int16 value dereferenced if the passed -// in pointer was not nil. Returns a int16 zero value if the -// pointer was nil. -func ToInt16(p *int16) (v int16) { - if p == nil { - return v - } - - return *p -} - -// ToInt16Slice returns a slice of int16 values, that are -// dereferenced if the passed in pointer was not nil. Returns a int16 -// zero value if the pointer was nil. -func ToInt16Slice(vs []*int16) []int16 { - ps := make([]int16, len(vs)) - for i, v := range vs { - ps[i] = ToInt16(v) - } - - return ps -} - -// ToInt16Map returns a map of int16 values, that are -// dereferenced if the passed in pointer was not nil. The int16 -// zero value is used if the pointer was nil. -func ToInt16Map(vs map[string]*int16) map[string]int16 { - ps := make(map[string]int16, len(vs)) - for k, v := range vs { - ps[k] = ToInt16(v) - } - - return ps -} - -// ToInt32 returns int32 value dereferenced if the passed -// in pointer was not nil. Returns a int32 zero value if the -// pointer was nil. -func ToInt32(p *int32) (v int32) { - if p == nil { - return v - } - - return *p -} - -// ToInt32Slice returns a slice of int32 values, that are -// dereferenced if the passed in pointer was not nil. Returns a int32 -// zero value if the pointer was nil. -func ToInt32Slice(vs []*int32) []int32 { - ps := make([]int32, len(vs)) - for i, v := range vs { - ps[i] = ToInt32(v) - } - - return ps -} - -// ToInt32Map returns a map of int32 values, that are -// dereferenced if the passed in pointer was not nil. The int32 -// zero value is used if the pointer was nil. -func ToInt32Map(vs map[string]*int32) map[string]int32 { - ps := make(map[string]int32, len(vs)) - for k, v := range vs { - ps[k] = ToInt32(v) - } - - return ps -} - -// ToInt64 returns int64 value dereferenced if the passed -// in pointer was not nil. Returns a int64 zero value if the -// pointer was nil. -func ToInt64(p *int64) (v int64) { - if p == nil { - return v - } - - return *p -} - -// ToInt64Slice returns a slice of int64 values, that are -// dereferenced if the passed in pointer was not nil. Returns a int64 -// zero value if the pointer was nil. -func ToInt64Slice(vs []*int64) []int64 { - ps := make([]int64, len(vs)) - for i, v := range vs { - ps[i] = ToInt64(v) - } - - return ps -} - -// ToInt64Map returns a map of int64 values, that are -// dereferenced if the passed in pointer was not nil. The int64 -// zero value is used if the pointer was nil. -func ToInt64Map(vs map[string]*int64) map[string]int64 { - ps := make(map[string]int64, len(vs)) - for k, v := range vs { - ps[k] = ToInt64(v) - } - - return ps -} - -// ToUint returns uint value dereferenced if the passed -// in pointer was not nil. Returns a uint zero value if the -// pointer was nil. -func ToUint(p *uint) (v uint) { - if p == nil { - return v - } - - return *p -} - -// ToUintSlice returns a slice of uint values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint -// zero value if the pointer was nil. -func ToUintSlice(vs []*uint) []uint { - ps := make([]uint, len(vs)) - for i, v := range vs { - ps[i] = ToUint(v) - } - - return ps -} - -// ToUintMap returns a map of uint values, that are -// dereferenced if the passed in pointer was not nil. The uint -// zero value is used if the pointer was nil. -func ToUintMap(vs map[string]*uint) map[string]uint { - ps := make(map[string]uint, len(vs)) - for k, v := range vs { - ps[k] = ToUint(v) - } - - return ps -} - -// ToUint8 returns uint8 value dereferenced if the passed -// in pointer was not nil. Returns a uint8 zero value if the -// pointer was nil. -func ToUint8(p *uint8) (v uint8) { - if p == nil { - return v - } - - return *p -} - -// ToUint8Slice returns a slice of uint8 values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint8 -// zero value if the pointer was nil. -func ToUint8Slice(vs []*uint8) []uint8 { - ps := make([]uint8, len(vs)) - for i, v := range vs { - ps[i] = ToUint8(v) - } - - return ps -} - -// ToUint8Map returns a map of uint8 values, that are -// dereferenced if the passed in pointer was not nil. The uint8 -// zero value is used if the pointer was nil. -func ToUint8Map(vs map[string]*uint8) map[string]uint8 { - ps := make(map[string]uint8, len(vs)) - for k, v := range vs { - ps[k] = ToUint8(v) - } - - return ps -} - -// ToUint16 returns uint16 value dereferenced if the passed -// in pointer was not nil. Returns a uint16 zero value if the -// pointer was nil. -func ToUint16(p *uint16) (v uint16) { - if p == nil { - return v - } - - return *p -} - -// ToUint16Slice returns a slice of uint16 values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint16 -// zero value if the pointer was nil. -func ToUint16Slice(vs []*uint16) []uint16 { - ps := make([]uint16, len(vs)) - for i, v := range vs { - ps[i] = ToUint16(v) - } - - return ps -} - -// ToUint16Map returns a map of uint16 values, that are -// dereferenced if the passed in pointer was not nil. The uint16 -// zero value is used if the pointer was nil. -func ToUint16Map(vs map[string]*uint16) map[string]uint16 { - ps := make(map[string]uint16, len(vs)) - for k, v := range vs { - ps[k] = ToUint16(v) - } - - return ps -} - -// ToUint32 returns uint32 value dereferenced if the passed -// in pointer was not nil. Returns a uint32 zero value if the -// pointer was nil. -func ToUint32(p *uint32) (v uint32) { - if p == nil { - return v - } - - return *p -} - -// ToUint32Slice returns a slice of uint32 values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint32 -// zero value if the pointer was nil. -func ToUint32Slice(vs []*uint32) []uint32 { - ps := make([]uint32, len(vs)) - for i, v := range vs { - ps[i] = ToUint32(v) - } - - return ps -} - -// ToUint32Map returns a map of uint32 values, that are -// dereferenced if the passed in pointer was not nil. The uint32 -// zero value is used if the pointer was nil. -func ToUint32Map(vs map[string]*uint32) map[string]uint32 { - ps := make(map[string]uint32, len(vs)) - for k, v := range vs { - ps[k] = ToUint32(v) - } - - return ps -} - -// ToUint64 returns uint64 value dereferenced if the passed -// in pointer was not nil. Returns a uint64 zero value if the -// pointer was nil. -func ToUint64(p *uint64) (v uint64) { - if p == nil { - return v - } - - return *p -} - -// ToUint64Slice returns a slice of uint64 values, that are -// dereferenced if the passed in pointer was not nil. Returns a uint64 -// zero value if the pointer was nil. -func ToUint64Slice(vs []*uint64) []uint64 { - ps := make([]uint64, len(vs)) - for i, v := range vs { - ps[i] = ToUint64(v) - } - - return ps -} - -// ToUint64Map returns a map of uint64 values, that are -// dereferenced if the passed in pointer was not nil. The uint64 -// zero value is used if the pointer was nil. -func ToUint64Map(vs map[string]*uint64) map[string]uint64 { - ps := make(map[string]uint64, len(vs)) - for k, v := range vs { - ps[k] = ToUint64(v) - } - - return ps -} - -// ToFloat32 returns float32 value dereferenced if the passed -// in pointer was not nil. Returns a float32 zero value if the -// pointer was nil. -func ToFloat32(p *float32) (v float32) { - if p == nil { - return v - } - - return *p -} - -// ToFloat32Slice returns a slice of float32 values, that are -// dereferenced if the passed in pointer was not nil. Returns a float32 -// zero value if the pointer was nil. -func ToFloat32Slice(vs []*float32) []float32 { - ps := make([]float32, len(vs)) - for i, v := range vs { - ps[i] = ToFloat32(v) - } - - return ps -} - -// ToFloat32Map returns a map of float32 values, that are -// dereferenced if the passed in pointer was not nil. The float32 -// zero value is used if the pointer was nil. -func ToFloat32Map(vs map[string]*float32) map[string]float32 { - ps := make(map[string]float32, len(vs)) - for k, v := range vs { - ps[k] = ToFloat32(v) - } - - return ps -} - -// ToFloat64 returns float64 value dereferenced if the passed -// in pointer was not nil. Returns a float64 zero value if the -// pointer was nil. -func ToFloat64(p *float64) (v float64) { - if p == nil { - return v - } - - return *p -} - -// ToFloat64Slice returns a slice of float64 values, that are -// dereferenced if the passed in pointer was not nil. Returns a float64 -// zero value if the pointer was nil. -func ToFloat64Slice(vs []*float64) []float64 { - ps := make([]float64, len(vs)) - for i, v := range vs { - ps[i] = ToFloat64(v) - } - - return ps -} - -// ToFloat64Map returns a map of float64 values, that are -// dereferenced if the passed in pointer was not nil. The float64 -// zero value is used if the pointer was nil. -func ToFloat64Map(vs map[string]*float64) map[string]float64 { - ps := make(map[string]float64, len(vs)) - for k, v := range vs { - ps[k] = ToFloat64(v) - } - - return ps -} - -// ToTime returns time.Time value dereferenced if the passed -// in pointer was not nil. Returns a time.Time zero value if the -// pointer was nil. -func ToTime(p *time.Time) (v time.Time) { - if p == nil { - return v - } - - return *p -} - -// ToTimeSlice returns a slice of time.Time values, that are -// dereferenced if the passed in pointer was not nil. Returns a time.Time -// zero value if the pointer was nil. -func ToTimeSlice(vs []*time.Time) []time.Time { - ps := make([]time.Time, len(vs)) - for i, v := range vs { - ps[i] = ToTime(v) - } - - return ps -} - -// ToTimeMap returns a map of time.Time values, that are -// dereferenced if the passed in pointer was not nil. The time.Time -// zero value is used if the pointer was nil. -func ToTimeMap(vs map[string]*time.Time) map[string]time.Time { - ps := make(map[string]time.Time, len(vs)) - for k, v := range vs { - ps[k] = ToTime(v) - } - - return ps -} - -// ToDuration returns time.Duration value dereferenced if the passed -// in pointer was not nil. Returns a time.Duration zero value if the -// pointer was nil. -func ToDuration(p *time.Duration) (v time.Duration) { - if p == nil { - return v - } - - return *p -} - -// ToDurationSlice returns a slice of time.Duration values, that are -// dereferenced if the passed in pointer was not nil. Returns a time.Duration -// zero value if the pointer was nil. -func ToDurationSlice(vs []*time.Duration) []time.Duration { - ps := make([]time.Duration, len(vs)) - for i, v := range vs { - ps[i] = ToDuration(v) - } - - return ps -} - -// ToDurationMap returns a map of time.Duration values, that are -// dereferenced if the passed in pointer was not nil. The time.Duration -// zero value is used if the pointer was nil. -func ToDurationMap(vs map[string]*time.Duration) map[string]time.Duration { - ps := make(map[string]time.Duration, len(vs)) - for k, v := range vs { - ps[k] = ToDuration(v) - } - - return ps -} diff --git a/vendor/github.com/aws/smithy-go/ptr/gen_scalars.go b/vendor/github.com/aws/smithy-go/ptr/gen_scalars.go deleted file mode 100644 index 97f0101..0000000 --- a/vendor/github.com/aws/smithy-go/ptr/gen_scalars.go +++ /dev/null @@ -1,83 +0,0 @@ -//go:build codegen -// +build codegen - -package ptr - -import "strings" - -func GetScalars() Scalars { - return Scalars{ - {Type: "bool"}, - {Type: "byte"}, - {Type: "string"}, - {Type: "int"}, - {Type: "int8"}, - {Type: "int16"}, - {Type: "int32"}, - {Type: "int64"}, - {Type: "uint"}, - {Type: "uint8"}, - {Type: "uint16"}, - {Type: "uint32"}, - {Type: "uint64"}, - {Type: "float32"}, - {Type: "float64"}, - {Type: "Time", Import: &Import{Path: "time"}}, - {Type: "Duration", Import: &Import{Path: "time"}}, - } -} - -// Import provides the import path and optional alias -type Import struct { - Path string - Alias string -} - -// Package returns the Go package name for the import. Returns alias if set. -func (i Import) Package() string { - if v := i.Alias; len(v) != 0 { - return v - } - - if v := i.Path; len(v) != 0 { - parts := strings.Split(v, "/") - pkg := parts[len(parts)-1] - return pkg - } - - return "" -} - -// Scalar provides the definition of a type to generate pointer utilities for. -type Scalar struct { - Type string - Import *Import -} - -// Name returns the exported function name for the type. -func (t Scalar) Name() string { - return strings.Title(t.Type) -} - -// Symbol returns the scalar's Go symbol with path if needed. -func (t Scalar) Symbol() string { - if t.Import != nil { - return t.Import.Package() + "." + t.Type - } - return t.Type -} - -// Scalars is a list of scalars. -type Scalars []Scalar - -// Imports returns all imports for the scalars. -func (ts Scalars) Imports() []*Import { - imports := []*Import{} - for _, t := range ts { - if v := t.Import; v != nil { - imports = append(imports, v) - } - } - - return imports -} diff --git a/vendor/github.com/aws/smithy-go/ptr/to_ptr.go b/vendor/github.com/aws/smithy-go/ptr/to_ptr.go deleted file mode 100644 index 0bfbbec..0000000 --- a/vendor/github.com/aws/smithy-go/ptr/to_ptr.go +++ /dev/null @@ -1,499 +0,0 @@ -// Code generated by smithy-go/ptr/generate.go DO NOT EDIT. -package ptr - -import ( - "time" -) - -// Bool returns a pointer value for the bool value passed in. -func Bool(v bool) *bool { - return &v -} - -// BoolSlice returns a slice of bool pointers from the values -// passed in. -func BoolSlice(vs []bool) []*bool { - ps := make([]*bool, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// BoolMap returns a map of bool pointers from the values -// passed in. -func BoolMap(vs map[string]bool) map[string]*bool { - ps := make(map[string]*bool, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Byte returns a pointer value for the byte value passed in. -func Byte(v byte) *byte { - return &v -} - -// ByteSlice returns a slice of byte pointers from the values -// passed in. -func ByteSlice(vs []byte) []*byte { - ps := make([]*byte, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// ByteMap returns a map of byte pointers from the values -// passed in. -func ByteMap(vs map[string]byte) map[string]*byte { - ps := make(map[string]*byte, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// String returns a pointer value for the string value passed in. -func String(v string) *string { - return &v -} - -// StringSlice returns a slice of string pointers from the values -// passed in. -func StringSlice(vs []string) []*string { - ps := make([]*string, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// StringMap returns a map of string pointers from the values -// passed in. -func StringMap(vs map[string]string) map[string]*string { - ps := make(map[string]*string, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Int returns a pointer value for the int value passed in. -func Int(v int) *int { - return &v -} - -// IntSlice returns a slice of int pointers from the values -// passed in. -func IntSlice(vs []int) []*int { - ps := make([]*int, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// IntMap returns a map of int pointers from the values -// passed in. -func IntMap(vs map[string]int) map[string]*int { - ps := make(map[string]*int, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Int8 returns a pointer value for the int8 value passed in. -func Int8(v int8) *int8 { - return &v -} - -// Int8Slice returns a slice of int8 pointers from the values -// passed in. -func Int8Slice(vs []int8) []*int8 { - ps := make([]*int8, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Int8Map returns a map of int8 pointers from the values -// passed in. -func Int8Map(vs map[string]int8) map[string]*int8 { - ps := make(map[string]*int8, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Int16 returns a pointer value for the int16 value passed in. -func Int16(v int16) *int16 { - return &v -} - -// Int16Slice returns a slice of int16 pointers from the values -// passed in. -func Int16Slice(vs []int16) []*int16 { - ps := make([]*int16, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Int16Map returns a map of int16 pointers from the values -// passed in. -func Int16Map(vs map[string]int16) map[string]*int16 { - ps := make(map[string]*int16, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Int32 returns a pointer value for the int32 value passed in. -func Int32(v int32) *int32 { - return &v -} - -// Int32Slice returns a slice of int32 pointers from the values -// passed in. -func Int32Slice(vs []int32) []*int32 { - ps := make([]*int32, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Int32Map returns a map of int32 pointers from the values -// passed in. -func Int32Map(vs map[string]int32) map[string]*int32 { - ps := make(map[string]*int32, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Int64 returns a pointer value for the int64 value passed in. -func Int64(v int64) *int64 { - return &v -} - -// Int64Slice returns a slice of int64 pointers from the values -// passed in. -func Int64Slice(vs []int64) []*int64 { - ps := make([]*int64, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Int64Map returns a map of int64 pointers from the values -// passed in. -func Int64Map(vs map[string]int64) map[string]*int64 { - ps := make(map[string]*int64, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Uint returns a pointer value for the uint value passed in. -func Uint(v uint) *uint { - return &v -} - -// UintSlice returns a slice of uint pointers from the values -// passed in. -func UintSlice(vs []uint) []*uint { - ps := make([]*uint, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// UintMap returns a map of uint pointers from the values -// passed in. -func UintMap(vs map[string]uint) map[string]*uint { - ps := make(map[string]*uint, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Uint8 returns a pointer value for the uint8 value passed in. -func Uint8(v uint8) *uint8 { - return &v -} - -// Uint8Slice returns a slice of uint8 pointers from the values -// passed in. -func Uint8Slice(vs []uint8) []*uint8 { - ps := make([]*uint8, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Uint8Map returns a map of uint8 pointers from the values -// passed in. -func Uint8Map(vs map[string]uint8) map[string]*uint8 { - ps := make(map[string]*uint8, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Uint16 returns a pointer value for the uint16 value passed in. -func Uint16(v uint16) *uint16 { - return &v -} - -// Uint16Slice returns a slice of uint16 pointers from the values -// passed in. -func Uint16Slice(vs []uint16) []*uint16 { - ps := make([]*uint16, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Uint16Map returns a map of uint16 pointers from the values -// passed in. -func Uint16Map(vs map[string]uint16) map[string]*uint16 { - ps := make(map[string]*uint16, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Uint32 returns a pointer value for the uint32 value passed in. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint32Slice returns a slice of uint32 pointers from the values -// passed in. -func Uint32Slice(vs []uint32) []*uint32 { - ps := make([]*uint32, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Uint32Map returns a map of uint32 pointers from the values -// passed in. -func Uint32Map(vs map[string]uint32) map[string]*uint32 { - ps := make(map[string]*uint32, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Uint64 returns a pointer value for the uint64 value passed in. -func Uint64(v uint64) *uint64 { - return &v -} - -// Uint64Slice returns a slice of uint64 pointers from the values -// passed in. -func Uint64Slice(vs []uint64) []*uint64 { - ps := make([]*uint64, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Uint64Map returns a map of uint64 pointers from the values -// passed in. -func Uint64Map(vs map[string]uint64) map[string]*uint64 { - ps := make(map[string]*uint64, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Float32 returns a pointer value for the float32 value passed in. -func Float32(v float32) *float32 { - return &v -} - -// Float32Slice returns a slice of float32 pointers from the values -// passed in. -func Float32Slice(vs []float32) []*float32 { - ps := make([]*float32, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Float32Map returns a map of float32 pointers from the values -// passed in. -func Float32Map(vs map[string]float32) map[string]*float32 { - ps := make(map[string]*float32, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Float64 returns a pointer value for the float64 value passed in. -func Float64(v float64) *float64 { - return &v -} - -// Float64Slice returns a slice of float64 pointers from the values -// passed in. -func Float64Slice(vs []float64) []*float64 { - ps := make([]*float64, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// Float64Map returns a map of float64 pointers from the values -// passed in. -func Float64Map(vs map[string]float64) map[string]*float64 { - ps := make(map[string]*float64, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Time returns a pointer value for the time.Time value passed in. -func Time(v time.Time) *time.Time { - return &v -} - -// TimeSlice returns a slice of time.Time pointers from the values -// passed in. -func TimeSlice(vs []time.Time) []*time.Time { - ps := make([]*time.Time, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// TimeMap returns a map of time.Time pointers from the values -// passed in. -func TimeMap(vs map[string]time.Time) map[string]*time.Time { - ps := make(map[string]*time.Time, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} - -// Duration returns a pointer value for the time.Duration value passed in. -func Duration(v time.Duration) *time.Duration { - return &v -} - -// DurationSlice returns a slice of time.Duration pointers from the values -// passed in. -func DurationSlice(vs []time.Duration) []*time.Duration { - ps := make([]*time.Duration, len(vs)) - for i, v := range vs { - vv := v - ps[i] = &vv - } - - return ps -} - -// DurationMap returns a map of time.Duration pointers from the values -// passed in. -func DurationMap(vs map[string]time.Duration) map[string]*time.Duration { - ps := make(map[string]*time.Duration, len(vs)) - for k, v := range vs { - vv := v - ps[k] = &vv - } - - return ps -} diff --git a/vendor/github.com/aws/smithy-go/rand/doc.go b/vendor/github.com/aws/smithy-go/rand/doc.go deleted file mode 100644 index f8b25d5..0000000 --- a/vendor/github.com/aws/smithy-go/rand/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package rand provides utilities for creating and working with random value -// generators. -package rand diff --git a/vendor/github.com/aws/smithy-go/rand/rand.go b/vendor/github.com/aws/smithy-go/rand/rand.go deleted file mode 100644 index 9c479f6..0000000 --- a/vendor/github.com/aws/smithy-go/rand/rand.go +++ /dev/null @@ -1,31 +0,0 @@ -package rand - -import ( - "crypto/rand" - "fmt" - "io" - "math/big" -) - -func init() { - Reader = rand.Reader -} - -// Reader provides a random reader that can reset during testing. -var Reader io.Reader - -// Int63n returns a int64 between zero and value of max, read from an io.Reader source. -func Int63n(reader io.Reader, max int64) (int64, error) { - bi, err := rand.Int(reader, big.NewInt(max)) - if err != nil { - return 0, fmt.Errorf("failed to read random value, %w", err) - } - - return bi.Int64(), nil -} - -// CryptoRandInt63n returns a random int64 between zero and value of max -// obtained from the crypto rand source. -func CryptoRandInt63n(max int64) (int64, error) { - return Int63n(Reader, max) -} diff --git a/vendor/github.com/aws/smithy-go/rand/uuid.go b/vendor/github.com/aws/smithy-go/rand/uuid.go deleted file mode 100644 index dc81cbc..0000000 --- a/vendor/github.com/aws/smithy-go/rand/uuid.go +++ /dev/null @@ -1,87 +0,0 @@ -package rand - -import ( - "encoding/hex" - "io" -) - -const dash byte = '-' - -// UUIDIdempotencyToken provides a utility to get idempotency tokens in the -// UUID format. -type UUIDIdempotencyToken struct { - uuid *UUID -} - -// NewUUIDIdempotencyToken returns a idempotency token provider returning -// tokens in the UUID random format using the reader provided. -func NewUUIDIdempotencyToken(r io.Reader) *UUIDIdempotencyToken { - return &UUIDIdempotencyToken{uuid: NewUUID(r)} -} - -// GetIdempotencyToken returns a random UUID value for Idempotency token. -func (u UUIDIdempotencyToken) GetIdempotencyToken() (string, error) { - return u.uuid.GetUUID() -} - -// UUID provides computing random UUID version 4 values from a random source -// reader. -type UUID struct { - randSrc io.Reader -} - -// NewUUID returns an initialized UUID value that can be used to retrieve -// random UUID version 4 values. -func NewUUID(r io.Reader) *UUID { - return &UUID{randSrc: r} -} - -// GetUUID returns a random UUID version 4 string representation sourced from the random reader the -// UUID was created with. Returns an error if unable to compute the UUID. -func (r *UUID) GetUUID() (string, error) { - var b [16]byte - if _, err := io.ReadFull(r.randSrc, b[:]); err != nil { - return "", err - } - r.makeUUIDv4(b[:]) - return format(b), nil -} - -// GetBytes returns a byte slice containing a random UUID version 4 sourced from the random reader the -// UUID was created with. Returns an error if unable to compute the UUID. -func (r *UUID) GetBytes() (u []byte, err error) { - u = make([]byte, 16) - if _, err = io.ReadFull(r.randSrc, u); err != nil { - return u, err - } - r.makeUUIDv4(u) - return u, nil -} - -func (r *UUID) makeUUIDv4(u []byte) { - // 13th character is "4" - u[6] = (u[6] & 0x0f) | 0x40 // Version 4 - // 17th character is "8", "9", "a", or "b" - u[8] = (u[8] & 0x3f) | 0x80 // Variant most significant bits are 10x where x can be either 1 or 0 -} - -// Format returns the canonical text representation of a UUID. -// This implementation is optimized to not use fmt. -// Example: 82e42f16-b6cc-4d5b-95f5-d403c4befd3d -func format(u [16]byte) string { - // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 - - var scratch [36]byte - - hex.Encode(scratch[:8], u[0:4]) - scratch[8] = dash - hex.Encode(scratch[9:13], u[4:6]) - scratch[13] = dash - hex.Encode(scratch[14:18], u[6:8]) - scratch[18] = dash - hex.Encode(scratch[19:23], u[8:10]) - scratch[23] = dash - hex.Encode(scratch[24:], u[10:]) - - return string(scratch[:]) -} diff --git a/vendor/github.com/aws/smithy-go/time/time.go b/vendor/github.com/aws/smithy-go/time/time.go deleted file mode 100644 index b552a09..0000000 --- a/vendor/github.com/aws/smithy-go/time/time.go +++ /dev/null @@ -1,134 +0,0 @@ -package time - -import ( - "context" - "fmt" - "math/big" - "strings" - "time" -) - -const ( - // dateTimeFormat is a IMF-fixdate formatted RFC3339 section 5.6 - dateTimeFormatInput = "2006-01-02T15:04:05.999999999Z" - dateTimeFormatInputNoZ = "2006-01-02T15:04:05.999999999" - dateTimeFormatOutput = "2006-01-02T15:04:05.999Z" - - // httpDateFormat is a date time defined by RFC 7231#section-7.1.1.1 - // IMF-fixdate with no UTC offset. - httpDateFormat = "Mon, 02 Jan 2006 15:04:05 GMT" - // Additional formats needed for compatibility. - httpDateFormatSingleDigitDay = "Mon, _2 Jan 2006 15:04:05 GMT" - httpDateFormatSingleDigitDayTwoDigitYear = "Mon, _2 Jan 06 15:04:05 GMT" -) - -var millisecondFloat = big.NewFloat(1e3) - -// FormatDateTime formats value as a date-time, (RFC3339 section 5.6) -// -// Example: 1985-04-12T23:20:50.52Z -func FormatDateTime(value time.Time) string { - return value.UTC().Format(dateTimeFormatOutput) -} - -// ParseDateTime parses a string as a date-time, (RFC3339 section 5.6) -// -// Example: 1985-04-12T23:20:50.52Z -func ParseDateTime(value string) (time.Time, error) { - return tryParse(value, - dateTimeFormatInput, - dateTimeFormatInputNoZ, - time.RFC3339Nano, - time.RFC3339, - ) -} - -// FormatHTTPDate formats value as a http-date, (RFC 7231#section-7.1.1.1 IMF-fixdate) -// -// Example: Tue, 29 Apr 2014 18:30:38 GMT -func FormatHTTPDate(value time.Time) string { - return value.UTC().Format(httpDateFormat) -} - -// ParseHTTPDate parses a string as a http-date, (RFC 7231#section-7.1.1.1 IMF-fixdate) -// -// Example: Tue, 29 Apr 2014 18:30:38 GMT -func ParseHTTPDate(value string) (time.Time, error) { - return tryParse(value, - httpDateFormat, - httpDateFormatSingleDigitDay, - httpDateFormatSingleDigitDayTwoDigitYear, - time.RFC850, - time.ANSIC, - ) -} - -// FormatEpochSeconds returns value as a Unix time in seconds with with decimal precision -// -// Example: 1515531081.123 -func FormatEpochSeconds(value time.Time) float64 { - ms := value.UnixNano() / int64(time.Millisecond) - return float64(ms) / 1e3 -} - -// ParseEpochSeconds returns value as a Unix time in seconds with with decimal precision -// -// Example: 1515531081.123 -func ParseEpochSeconds(value float64) time.Time { - f := big.NewFloat(value) - f = f.Mul(f, millisecondFloat) - i, _ := f.Int64() - // Offset to `UTC` because time.Unix returns the time value based on system - // local setting. - return time.Unix(0, i*1e6).UTC() -} - -func tryParse(v string, formats ...string) (time.Time, error) { - var errs parseErrors - for _, f := range formats { - t, err := time.Parse(f, v) - if err != nil { - errs = append(errs, parseError{ - Format: f, - Err: err, - }) - continue - } - return t, nil - } - - return time.Time{}, fmt.Errorf("unable to parse time string, %w", errs) -} - -type parseErrors []parseError - -func (es parseErrors) Error() string { - var s strings.Builder - for _, e := range es { - fmt.Fprintf(&s, "\n * %q: %v", e.Format, e.Err) - } - - return "parse errors:" + s.String() -} - -type parseError struct { - Format string - Err error -} - -// SleepWithContext will wait for the timer duration to expire, or until the context -// is canceled. Whichever happens first. If the context is canceled the -// Context's error will be returned. -func SleepWithContext(ctx context.Context, dur time.Duration) error { - t := time.NewTimer(dur) - defer t.Stop() - - select { - case <-t.C: - break - case <-ctx.Done(): - return ctx.Err() - } - - return nil -} diff --git a/vendor/github.com/aws/smithy-go/tracing/context.go b/vendor/github.com/aws/smithy-go/tracing/context.go deleted file mode 100644 index a404ed9..0000000 --- a/vendor/github.com/aws/smithy-go/tracing/context.go +++ /dev/null @@ -1,96 +0,0 @@ -package tracing - -import "context" - -type ( - operationTracerKey struct{} - spanLineageKey struct{} -) - -// GetSpan returns the active trace Span on the context. -// -// The boolean in the return indicates whether a Span was actually in the -// context, but a no-op implementation will be returned if not, so callers -// can generally disregard the boolean unless they wish to explicitly confirm -// presence/absence of a Span. -func GetSpan(ctx context.Context) (Span, bool) { - lineage := getLineage(ctx) - if len(lineage) == 0 { - return nopSpan{}, false - } - - return lineage[len(lineage)-1], true -} - -// WithSpan sets the active trace Span on the context. -func WithSpan(parent context.Context, span Span) context.Context { - lineage := getLineage(parent) - if len(lineage) == 0 { - return context.WithValue(parent, spanLineageKey{}, []Span{span}) - } - - lineage = append(lineage, span) - return context.WithValue(parent, spanLineageKey{}, lineage) -} - -// PopSpan pops the current Span off the context, setting the active Span on -// the returned Context back to its parent and returning the REMOVED one. -// -// PopSpan on a context with no active Span will return a no-op instance. -// -// This is mostly necessary for the runtime to manage base trace spans due to -// the wrapped-function nature of the middleware stack. End-users of Smithy -// clients SHOULD NOT generally be using this API. -func PopSpan(parent context.Context) (context.Context, Span) { - lineage := getLineage(parent) - if len(lineage) == 0 { - return parent, nopSpan{} - } - - span := lineage[len(lineage)-1] - lineage = lineage[:len(lineage)-1] - return context.WithValue(parent, spanLineageKey{}, lineage), span -} - -func getLineage(ctx context.Context) []Span { - v := ctx.Value(spanLineageKey{}) - if v == nil { - return nil - } - - return v.([]Span) -} - -// GetOperationTracer returns the embedded operation-scoped Tracer on a -// Context. -// -// The boolean in the return indicates whether a Tracer was actually in the -// context, but a no-op implementation will be returned if not, so callers -// can generally disregard the boolean unless they wish to explicitly confirm -// presence/absence of a Tracer. -func GetOperationTracer(ctx context.Context) (Tracer, bool) { - v := ctx.Value(operationTracerKey{}) - if v == nil { - return nopTracer{}, false - } - - return v.(Tracer), true -} - -// WithOperationTracer returns a child Context embedding the given Tracer. -// -// The runtime will use this embed a scoped tracer for client operations, -// Smithy/SDK client callers DO NOT need to do this explicitly. -func WithOperationTracer(parent context.Context, tracer Tracer) context.Context { - return context.WithValue(parent, operationTracerKey{}, tracer) -} - -// StartSpan is a convenience API for creating tracing Spans from a Context. -// -// StartSpan uses the operation-scoped Tracer, previously stored using -// [WithOperationTracer], to start the Span. If a Tracer has not been embedded -// the returned Span will be a no-op implementation. -func StartSpan(ctx context.Context, name string, opts ...SpanOption) (context.Context, Span) { - tracer, _ := GetOperationTracer(ctx) - return tracer.StartSpan(ctx, name, opts...) -} diff --git a/vendor/github.com/aws/smithy-go/tracing/nop.go b/vendor/github.com/aws/smithy-go/tracing/nop.go deleted file mode 100644 index 573d28b..0000000 --- a/vendor/github.com/aws/smithy-go/tracing/nop.go +++ /dev/null @@ -1,32 +0,0 @@ -package tracing - -import "context" - -// NopTracerProvider is a no-op tracing implementation. -type NopTracerProvider struct{} - -var _ TracerProvider = (*NopTracerProvider)(nil) - -// Tracer returns a tracer which creates no-op spans. -func (NopTracerProvider) Tracer(string, ...TracerOption) Tracer { - return nopTracer{} -} - -type nopTracer struct{} - -var _ Tracer = (*nopTracer)(nil) - -func (nopTracer) StartSpan(ctx context.Context, name string, opts ...SpanOption) (context.Context, Span) { - return ctx, nopSpan{} -} - -type nopSpan struct{} - -var _ Span = (*nopSpan)(nil) - -func (nopSpan) Name() string { return "" } -func (nopSpan) Context() SpanContext { return SpanContext{} } -func (nopSpan) AddEvent(string, ...EventOption) {} -func (nopSpan) SetProperty(any, any) {} -func (nopSpan) SetStatus(SpanStatus) {} -func (nopSpan) End() {} diff --git a/vendor/github.com/aws/smithy-go/tracing/tracing.go b/vendor/github.com/aws/smithy-go/tracing/tracing.go deleted file mode 100644 index 089ed39..0000000 --- a/vendor/github.com/aws/smithy-go/tracing/tracing.go +++ /dev/null @@ -1,95 +0,0 @@ -// Package tracing defines tracing APIs to be used by Smithy clients. -package tracing - -import ( - "context" - - "github.com/aws/smithy-go" -) - -// SpanStatus records the "success" state of an observed span. -type SpanStatus int - -// Enumeration of SpanStatus. -const ( - SpanStatusUnset SpanStatus = iota - SpanStatusOK - SpanStatusError -) - -// SpanKind indicates the nature of the work being performed. -type SpanKind int - -// Enumeration of SpanKind. -const ( - SpanKindInternal SpanKind = iota - SpanKindClient - SpanKindServer - SpanKindProducer - SpanKindConsumer -) - -// TracerProvider is the entry point for creating client traces. -type TracerProvider interface { - Tracer(scope string, opts ...TracerOption) Tracer -} - -// TracerOption applies configuration to a tracer. -type TracerOption func(o *TracerOptions) - -// TracerOptions represent configuration for tracers. -type TracerOptions struct { - Properties smithy.Properties -} - -// Tracer is the entry point for creating observed client Spans. -// -// Spans created by tracers propagate by existing on the Context. Consumers of -// the API can use [GetSpan] to pull the active Span from a Context. -// -// Creation of child Spans is implicit through Context persistence. If -// CreateSpan is called with a Context that holds a Span, the result will be a -// child of that Span. -type Tracer interface { - StartSpan(ctx context.Context, name string, opts ...SpanOption) (context.Context, Span) -} - -// SpanOption applies configuration to a span. -type SpanOption func(o *SpanOptions) - -// SpanOptions represent configuration for span events. -type SpanOptions struct { - Kind SpanKind - Properties smithy.Properties -} - -// Span records a conceptually individual unit of work that takes place in a -// Smithy client operation. -type Span interface { - Name() string - Context() SpanContext - AddEvent(name string, opts ...EventOption) - SetStatus(status SpanStatus) - SetProperty(k, v any) - End() -} - -// EventOption applies configuration to a span event. -type EventOption func(o *EventOptions) - -// EventOptions represent configuration for span events. -type EventOptions struct { - Properties smithy.Properties -} - -// SpanContext uniquely identifies a Span. -type SpanContext struct { - TraceID string - SpanID string - IsRemote bool -} - -// IsValid is true when a span has nonzero trace and span IDs. -func (ctx *SpanContext) IsValid() bool { - return len(ctx.TraceID) != 0 && len(ctx.SpanID) != 0 -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/auth.go b/vendor/github.com/aws/smithy-go/transport/http/auth.go deleted file mode 100644 index 58e1ab5..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/auth.go +++ /dev/null @@ -1,21 +0,0 @@ -package http - -import ( - "context" - - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/auth" -) - -// AuthScheme defines an HTTP authentication scheme. -type AuthScheme interface { - SchemeID() string - IdentityResolver(auth.IdentityResolverOptions) auth.IdentityResolver - Signer() Signer -} - -// Signer defines the interface through which HTTP requests are supplemented -// with an Identity. -type Signer interface { - SignRequest(context.Context, *Request, auth.Identity, smithy.Properties) error -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/auth_schemes.go b/vendor/github.com/aws/smithy-go/transport/http/auth_schemes.go deleted file mode 100644 index d60cf2a..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/auth_schemes.go +++ /dev/null @@ -1,45 +0,0 @@ -package http - -import ( - "context" - - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/auth" -) - -// NewAnonymousScheme returns the anonymous HTTP auth scheme. -func NewAnonymousScheme() AuthScheme { - return &authScheme{ - schemeID: auth.SchemeIDAnonymous, - signer: &nopSigner{}, - } -} - -// authScheme is parameterized to generically implement the exported AuthScheme -// interface -type authScheme struct { - schemeID string - signer Signer -} - -var _ AuthScheme = (*authScheme)(nil) - -func (s *authScheme) SchemeID() string { - return s.schemeID -} - -func (s *authScheme) IdentityResolver(o auth.IdentityResolverOptions) auth.IdentityResolver { - return o.GetIdentityResolver(s.schemeID) -} - -func (s *authScheme) Signer() Signer { - return s.signer -} - -type nopSigner struct{} - -var _ Signer = (*nopSigner)(nil) - -func (*nopSigner) SignRequest(context.Context, *Request, auth.Identity, smithy.Properties) error { - return nil -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/checksum_middleware.go b/vendor/github.com/aws/smithy-go/transport/http/checksum_middleware.go deleted file mode 100644 index bc4ad6e..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/checksum_middleware.go +++ /dev/null @@ -1,70 +0,0 @@ -package http - -import ( - "context" - "fmt" - - "github.com/aws/smithy-go/middleware" -) - -const contentMD5Header = "Content-Md5" - -// contentMD5Checksum provides a middleware to compute and set -// content-md5 checksum for a http request -type contentMD5Checksum struct { -} - -// AddContentChecksumMiddleware adds checksum middleware to middleware's -// build step. -func AddContentChecksumMiddleware(stack *middleware.Stack) error { - // This middleware must be executed before request body is set. - return stack.Build.Add(&contentMD5Checksum{}, middleware.Before) -} - -// ID returns the identifier for the checksum middleware -func (m *contentMD5Checksum) ID() string { return "ContentChecksum" } - -// HandleBuild adds behavior to compute md5 checksum and add content-md5 header -// on http request -func (m *contentMD5Checksum) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*Request) - if !ok { - return out, metadata, fmt.Errorf("unknown request type %T", req) - } - - // if Content-MD5 header is already present, return - if v := req.Header.Get(contentMD5Header); len(v) != 0 { - return next.HandleBuild(ctx, in) - } - - // fetch the request stream. - stream := req.GetStream() - // compute checksum if payload is explicit - if stream != nil { - if !req.IsStreamSeekable() { - return out, metadata, fmt.Errorf( - "unseekable stream is not supported for computing md5 checksum") - } - - v, err := computeMD5Checksum(stream) - if err != nil { - return out, metadata, fmt.Errorf("error computing md5 checksum, %w", err) - } - - // reset the request stream - if err := req.RewindStream(); err != nil { - return out, metadata, fmt.Errorf( - "error rewinding request stream after computing md5 checksum, %w", err) - } - - // set the 'Content-MD5' header - req.Header.Set(contentMD5Header, string(v)) - } - - // set md5 header value - return next.HandleBuild(ctx, in) -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/client.go b/vendor/github.com/aws/smithy-go/transport/http/client.go deleted file mode 100644 index 0fceae8..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/client.go +++ /dev/null @@ -1,161 +0,0 @@ -package http - -import ( - "context" - "fmt" - "net/http" - - smithy "github.com/aws/smithy-go" - "github.com/aws/smithy-go/metrics" - "github.com/aws/smithy-go/middleware" - "github.com/aws/smithy-go/tracing" -) - -// ClientDo provides the interface for custom HTTP client implementations. -type ClientDo interface { - Do(*http.Request) (*http.Response, error) -} - -// ClientDoFunc provides a helper to wrap a function as an HTTP client for -// round tripping requests. -type ClientDoFunc func(*http.Request) (*http.Response, error) - -// Do will invoke the underlying func, returning the result. -func (fn ClientDoFunc) Do(r *http.Request) (*http.Response, error) { - return fn(r) -} - -// ClientHandler wraps a client that implements the HTTP Do method. Standard -// implementation is http.Client. -type ClientHandler struct { - client ClientDo - - Meter metrics.Meter // For HTTP client metrics. -} - -// NewClientHandler returns an initialized middleware handler for the client. -// -// Deprecated: Use [NewClientHandlerWithOptions]. -func NewClientHandler(client ClientDo) ClientHandler { - return NewClientHandlerWithOptions(client) -} - -// NewClientHandlerWithOptions returns an initialized middleware handler for the client -// with applied options. -func NewClientHandlerWithOptions(client ClientDo, opts ...func(*ClientHandler)) ClientHandler { - h := ClientHandler{ - client: client, - } - for _, opt := range opts { - opt(&h) - } - if h.Meter == nil { - h.Meter = metrics.NopMeterProvider{}.Meter("") - } - return h -} - -// Handle implements the middleware Handler interface, that will invoke the -// underlying HTTP client. Requires the input to be a Smithy *Request. Returns -// a smithy *Response, or error if the request failed. -func (c ClientHandler) Handle(ctx context.Context, input interface{}) ( - out interface{}, metadata middleware.Metadata, err error, -) { - ctx, span := tracing.StartSpan(ctx, "DoHTTPRequest") - defer span.End() - - ctx, client, err := withMetrics(ctx, c.client, c.Meter) - if err != nil { - return nil, metadata, fmt.Errorf("instrument with HTTP metrics: %w", err) - } - - req, ok := input.(*Request) - if !ok { - return nil, metadata, fmt.Errorf("expect Smithy http.Request value as input, got unsupported type %T", input) - } - - builtRequest := req.Build(ctx) - if err := ValidateEndpointHost(builtRequest.Host); err != nil { - return nil, metadata, err - } - - span.SetProperty("http.method", req.Method) - span.SetProperty("http.request_content_length", -1) // at least indicate unknown - length, ok, err := req.StreamLength() - if err != nil { - return nil, metadata, err - } - if ok { - span.SetProperty("http.request_content_length", length) - } - - resp, err := client.Do(builtRequest) - if resp == nil { - // Ensure a http response value is always present to prevent unexpected - // panics. - resp = &http.Response{ - Header: http.Header{}, - Body: http.NoBody, - } - } - if err != nil { - err = &RequestSendError{Err: err} - - // Override the error with a context canceled error, if that was canceled. - select { - case <-ctx.Done(): - err = &smithy.CanceledError{Err: ctx.Err()} - default: - } - } - - // HTTP RoundTripper *should* close the request body. But this may not happen in a timely manner. - // So instead Smithy *Request Build wraps the body to be sent in a safe closer that will clear the - // stream reference so that it can be safely reused. - if builtRequest.Body != nil { - _ = builtRequest.Body.Close() - } - - span.SetProperty("net.protocol.version", fmt.Sprintf("%d.%d", resp.ProtoMajor, resp.ProtoMinor)) - span.SetProperty("http.status_code", resp.StatusCode) - span.SetProperty("http.response_content_length", resp.ContentLength) - - return &Response{Response: resp}, metadata, err -} - -// RequestSendError provides a generic request transport error. This error -// should wrap errors making HTTP client requests. -// -// The ClientHandler will wrap the HTTP client's error if the client request -// fails, and did not fail because of context canceled. -type RequestSendError struct { - Err error -} - -// ConnectionError returns that the error is related to not being able to send -// the request, or receive a response from the service. -func (e *RequestSendError) ConnectionError() bool { - return true -} - -// Unwrap returns the underlying error, if there was one. -func (e *RequestSendError) Unwrap() error { - return e.Err -} - -func (e *RequestSendError) Error() string { - return fmt.Sprintf("request send failed, %v", e.Err) -} - -// NopClient provides a client that ignores the request, and returns an empty -// successful HTTP response value. -type NopClient struct{} - -// Do ignores the request and returns a 200 status empty response. -func (NopClient) Do(r *http.Request) (*http.Response, error) { - return &http.Response{ - StatusCode: 200, - Header: http.Header{}, - Body: http.NoBody, - }, nil -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/doc.go b/vendor/github.com/aws/smithy-go/transport/http/doc.go deleted file mode 100644 index 07366ac..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/doc.go +++ /dev/null @@ -1,5 +0,0 @@ -/* -Package http provides the HTTP transport client and request/response types -needed to round trip API operation calls with an service. -*/ -package http diff --git a/vendor/github.com/aws/smithy-go/transport/http/headerlist.go b/vendor/github.com/aws/smithy-go/transport/http/headerlist.go deleted file mode 100644 index cbc9deb..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/headerlist.go +++ /dev/null @@ -1,163 +0,0 @@ -package http - -import ( - "fmt" - "strconv" - "strings" - "unicode" -) - -func splitHeaderListValues(vs []string, splitFn func(string) ([]string, error)) ([]string, error) { - values := make([]string, 0, len(vs)) - - for i := 0; i < len(vs); i++ { - parts, err := splitFn(vs[i]) - if err != nil { - return nil, err - } - values = append(values, parts...) - } - - return values, nil -} - -// SplitHeaderListValues attempts to split the elements of the slice by commas, -// and return a list of all values separated. Returns error if unable to -// separate the values. -func SplitHeaderListValues(vs []string) ([]string, error) { - return splitHeaderListValues(vs, quotedCommaSplit) -} - -func quotedCommaSplit(v string) (parts []string, err error) { - v = strings.TrimSpace(v) - - expectMore := true - for i := 0; i < len(v); i++ { - if unicode.IsSpace(rune(v[i])) { - continue - } - expectMore = false - - // leading space in part is ignored. - // Start of value must be non-space, or quote. - // - // - If quote, enter quoted mode, find next non-escaped quote to - // terminate the value. - // - Otherwise, find next comma to terminate value. - - remaining := v[i:] - - var value string - var valueLen int - if remaining[0] == '"' { - //------------------------------ - // Quoted value - //------------------------------ - var j int - var skipQuote bool - for j += 1; j < len(remaining); j++ { - if remaining[j] == '\\' || (remaining[j] != '\\' && skipQuote) { - skipQuote = !skipQuote - continue - } - if remaining[j] == '"' { - break - } - } - if j == len(remaining) || j == 1 { - return nil, fmt.Errorf("value %v missing closing double quote", - remaining) - } - valueLen = j + 1 - - tail := remaining[valueLen:] - var k int - for ; k < len(tail); k++ { - if !unicode.IsSpace(rune(tail[k])) && tail[k] != ',' { - return nil, fmt.Errorf("value %v has non-space trailing characters", - remaining) - } - if tail[k] == ',' { - expectMore = true - break - } - } - value = remaining[:valueLen] - value, err = strconv.Unquote(value) - if err != nil { - return nil, fmt.Errorf("failed to unquote value %v, %w", value, err) - } - - // Pad valueLen to include trailing space(s) so `i` is updated correctly. - valueLen += k - - } else { - //------------------------------ - // Unquoted value - //------------------------------ - - // Index of the next comma is the length of the value, or end of string. - valueLen = strings.Index(remaining, ",") - if valueLen != -1 { - expectMore = true - } else { - valueLen = len(remaining) - } - value = strings.TrimSpace(remaining[:valueLen]) - } - - i += valueLen - parts = append(parts, value) - - } - - if expectMore { - parts = append(parts, "") - } - - return parts, nil -} - -// SplitHTTPDateTimestampHeaderListValues attempts to split the HTTP-Date -// timestamp values in the slice by commas, and return a list of all values -// separated. The split is aware of the HTTP-Date timestamp format, and will skip -// comma within the timestamp value. Returns an error if unable to split the -// timestamp values. -func SplitHTTPDateTimestampHeaderListValues(vs []string) ([]string, error) { - return splitHeaderListValues(vs, splitHTTPDateHeaderValue) -} - -func splitHTTPDateHeaderValue(v string) ([]string, error) { - if n := strings.Count(v, ","); n <= 1 { - // Nothing to do if only contains a no, or single HTTPDate value - return []string{v}, nil - } else if n%2 == 0 { - return nil, fmt.Errorf("invalid timestamp HTTPDate header comma separations, %q", v) - } - - var parts []string - var i, j int - - var doSplit bool - for ; i < len(v); i++ { - if v[i] == ',' { - if doSplit { - doSplit = false - parts = append(parts, strings.TrimSpace(v[j:i])) - j = i + 1 - } else { - // Skip the first comma in the timestamp value since that - // separates the day from the rest of the timestamp. - // - // Tue, 17 Dec 2019 23:48:18 GMT - doSplit = true - } - } - } - // Add final part - if j < len(v) { - parts = append(parts, strings.TrimSpace(v[j:])) - } - - return parts, nil -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/host.go b/vendor/github.com/aws/smithy-go/transport/http/host.go deleted file mode 100644 index db9801b..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/host.go +++ /dev/null @@ -1,89 +0,0 @@ -package http - -import ( - "fmt" - "net" - "strconv" - "strings" -) - -// ValidateEndpointHost validates that the host string passed in is a valid RFC -// 3986 host. Returns error if the host is not valid. -func ValidateEndpointHost(host string) error { - var errors strings.Builder - var hostname string - var port string - var err error - - if strings.Contains(host, ":") { - hostname, port, err = net.SplitHostPort(host) - if err != nil { - errors.WriteString(fmt.Sprintf("\n endpoint %v, failed to parse, got ", host)) - errors.WriteString(err.Error()) - } - - if !ValidPortNumber(port) { - errors.WriteString(fmt.Sprintf("port number should be in range [0-65535], got %v", port)) - } - } else { - hostname = host - } - - labels := strings.Split(hostname, ".") - for i, label := range labels { - if i == len(labels)-1 && len(label) == 0 { - // Allow trailing dot for FQDN hosts. - continue - } - - if !ValidHostLabel(label) { - errors.WriteString("\nendpoint host domain labels must match \"[a-zA-Z0-9-]{1,63}\", but found: ") - errors.WriteString(label) - } - } - - if len(hostname) == 0 && len(port) != 0 { - errors.WriteString("\nendpoint host with port must not be empty") - } - - if len(hostname) > 255 { - errors.WriteString(fmt.Sprintf("\nendpoint host must be less than 255 characters, but was %d", len(hostname))) - } - - if len(errors.String()) > 0 { - return fmt.Errorf("invalid endpoint host%s", errors.String()) - } - return nil -} - -// ValidPortNumber returns whether the port is valid RFC 3986 port. -func ValidPortNumber(port string) bool { - i, err := strconv.Atoi(port) - if err != nil { - return false - } - - if i < 0 || i > 65535 { - return false - } - return true -} - -// ValidHostLabel returns whether the label is a valid RFC 3986 host label. -func ValidHostLabel(label string) bool { - if l := len(label); l == 0 || l > 63 { - return false - } - for _, r := range label { - switch { - case r >= '0' && r <= '9': - case r >= 'A' && r <= 'Z': - case r >= 'a' && r <= 'z': - case r == '-': - default: - return false - } - } - - return true -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/interceptor.go b/vendor/github.com/aws/smithy-go/transport/http/interceptor.go deleted file mode 100644 index e21f263..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/interceptor.go +++ /dev/null @@ -1,321 +0,0 @@ -package http - -import ( - "context" -) - -func icopy[T any](v []T) []T { - s := make([]T, len(v)) - copy(s, v) - return s -} - -// InterceptorContext is all the information available in different -// interceptors. -// -// Not all information is available in each interceptor, see each interface -// definition for more details. -type InterceptorContext struct { - Input any - Request *Request - - Output any - Response *Response -} - -// InterceptorRegistry holds a list of operation interceptors. -// -// Interceptors allow callers to insert custom behavior at well-defined points -// within a client's operation lifecycle. -// -// # Interceptor context -// -// All interceptors are invoked with a context object that contains input and -// output containers for the operation. The individual fields that are -// available will depend on what the interceptor is and, in certain -// interceptors, how far the operation was able to progress. See the -// documentation for each interface definition for more information about field -// availability. -// -// Implementations MUST NOT directly mutate the values of the fields in the -// interceptor context. They are free to mutate the existing values _pointed -// to_ by those fields, however. -// -// # Returning errors -// -// All interceptors can return errors. If an interceptor returns an error -// _before_ the client's retry loop, the operation will fail immediately. If -// one returns an error _within_ the retry loop, the error WILL be considered -// according to the client's retry policy. -// -// # Adding interceptors -// -// Idiomatically you will simply use one of the Add() receiver methods to -// register interceptors as desired. However, the list for each interface is -// exported on the registry struct and the caller is free to manipulate it -// directly, for example, to register a number of interceptors all at once, or -// to remove one that was previously registered. -// -// The base SDK client WILL NOT add any interceptors. SDK operations and -// customizations are implemented in terms of middleware. -// -// Modifications to the registry will not persist across operation calls when -// using per-operation functional options. This means you can register -// interceptors on a per-operation basis without affecting other operations. -type InterceptorRegistry struct { - BeforeExecution []BeforeExecutionInterceptor - BeforeSerialization []BeforeSerializationInterceptor - AfterSerialization []AfterSerializationInterceptor - BeforeRetryLoop []BeforeRetryLoopInterceptor - BeforeAttempt []BeforeAttemptInterceptor - BeforeSigning []BeforeSigningInterceptor - AfterSigning []AfterSigningInterceptor - BeforeTransmit []BeforeTransmitInterceptor - AfterTransmit []AfterTransmitInterceptor - BeforeDeserialization []BeforeDeserializationInterceptor - AfterDeserialization []AfterDeserializationInterceptor - AfterAttempt []AfterAttemptInterceptor - AfterExecution []AfterExecutionInterceptor -} - -// Copy returns a deep copy of the registry. This is used by SDK clients on -// each operation call in order to prevent per-op config mutation from -// persisting. -func (i *InterceptorRegistry) Copy() InterceptorRegistry { - return InterceptorRegistry{ - BeforeExecution: icopy(i.BeforeExecution), - BeforeSerialization: icopy(i.BeforeSerialization), - AfterSerialization: icopy(i.AfterSerialization), - BeforeRetryLoop: icopy(i.BeforeRetryLoop), - BeforeAttempt: icopy(i.BeforeAttempt), - BeforeSigning: icopy(i.BeforeSigning), - AfterSigning: icopy(i.AfterSigning), - BeforeTransmit: icopy(i.BeforeTransmit), - AfterTransmit: icopy(i.AfterTransmit), - BeforeDeserialization: icopy(i.BeforeDeserialization), - AfterDeserialization: icopy(i.AfterDeserialization), - AfterAttempt: icopy(i.AfterAttempt), - AfterExecution: icopy(i.AfterExecution), - } -} - -// AddBeforeExecution registers the provided BeforeExecutionInterceptor. -func (i *InterceptorRegistry) AddBeforeExecution(v BeforeExecutionInterceptor) { - i.BeforeExecution = append(i.BeforeExecution, v) -} - -// AddBeforeSerialization registers the provided BeforeSerializationInterceptor. -func (i *InterceptorRegistry) AddBeforeSerialization(v BeforeSerializationInterceptor) { - i.BeforeSerialization = append(i.BeforeSerialization, v) -} - -// AddAfterSerialization registers the provided AfterSerializationInterceptor. -func (i *InterceptorRegistry) AddAfterSerialization(v AfterSerializationInterceptor) { - i.AfterSerialization = append(i.AfterSerialization, v) -} - -// AddBeforeRetryLoop registers the provided BeforeRetryLoopInterceptor. -func (i *InterceptorRegistry) AddBeforeRetryLoop(v BeforeRetryLoopInterceptor) { - i.BeforeRetryLoop = append(i.BeforeRetryLoop, v) -} - -// AddBeforeAttempt registers the provided BeforeAttemptInterceptor. -func (i *InterceptorRegistry) AddBeforeAttempt(v BeforeAttemptInterceptor) { - i.BeforeAttempt = append(i.BeforeAttempt, v) -} - -// AddBeforeSigning registers the provided BeforeSigningInterceptor. -func (i *InterceptorRegistry) AddBeforeSigning(v BeforeSigningInterceptor) { - i.BeforeSigning = append(i.BeforeSigning, v) -} - -// AddAfterSigning registers the provided AfterSigningInterceptor. -func (i *InterceptorRegistry) AddAfterSigning(v AfterSigningInterceptor) { - i.AfterSigning = append(i.AfterSigning, v) -} - -// AddBeforeTransmit registers the provided BeforeTransmitInterceptor. -func (i *InterceptorRegistry) AddBeforeTransmit(v BeforeTransmitInterceptor) { - i.BeforeTransmit = append(i.BeforeTransmit, v) -} - -// AddAfterTransmit registers the provided AfterTransmitInterceptor. -func (i *InterceptorRegistry) AddAfterTransmit(v AfterTransmitInterceptor) { - i.AfterTransmit = append(i.AfterTransmit, v) -} - -// AddBeforeDeserialization registers the provided BeforeDeserializationInterceptor. -func (i *InterceptorRegistry) AddBeforeDeserialization(v BeforeDeserializationInterceptor) { - i.BeforeDeserialization = append(i.BeforeDeserialization, v) -} - -// AddAfterDeserialization registers the provided AfterDeserializationInterceptor. -func (i *InterceptorRegistry) AddAfterDeserialization(v AfterDeserializationInterceptor) { - i.AfterDeserialization = append(i.AfterDeserialization, v) -} - -// AddAfterAttempt registers the provided AfterAttemptInterceptor. -func (i *InterceptorRegistry) AddAfterAttempt(v AfterAttemptInterceptor) { - i.AfterAttempt = append(i.AfterAttempt, v) -} - -// AddAfterExecution registers the provided AfterExecutionInterceptor. -func (i *InterceptorRegistry) AddAfterExecution(v AfterExecutionInterceptor) { - i.AfterExecution = append(i.AfterExecution, v) -} - -// BeforeExecutionInterceptor runs before anything else in the operation -// lifecycle. -// -// Available InterceptorContext fields: -// - Input -type BeforeExecutionInterceptor interface { - BeforeExecution(ctx context.Context, in *InterceptorContext) error -} - -// BeforeSerializationInterceptor runs before the operation input is serialized -// into its transport request. -// -// Serialization occurs before the operation's retry loop. -// -// Available InterceptorContext fields: -// - Input -type BeforeSerializationInterceptor interface { - BeforeSerialization(ctx context.Context, in *InterceptorContext) error -} - -// AfterSerializationInterceptor runs after the operation input is serialized -// into its transport request. -// -// Available InterceptorContext fields: -// - Input -// - Request -type AfterSerializationInterceptor interface { - AfterSerialization(ctx context.Context, in *InterceptorContext) error -} - -// BeforeRetryLoopInterceptor runs right before the operation enters the retry loop. -// -// Available InterceptorContext fields: -// - Input -// - Request -type BeforeRetryLoopInterceptor interface { - BeforeRetryLoop(ctx context.Context, in *InterceptorContext) error -} - -// BeforeAttemptInterceptor runs right before every attempt in the retry loop. -// -// If this interceptor returns an error, AfterAttempt interceptors WILL NOT be -// invoked. -// -// Available InterceptorContext fields: -// - Input -// - Request -type BeforeAttemptInterceptor interface { - BeforeAttempt(ctx context.Context, in *InterceptorContext) error -} - -// BeforeSigningInterceptor runs right before the request is signed. -// -// Signing occurs within the operation's retry loop. -// -// Available InterceptorContext fields: -// - Input -// - Request -type BeforeSigningInterceptor interface { - BeforeSigning(ctx context.Context, in *InterceptorContext) error -} - -// AfterSigningInterceptor runs right after the request is signed. -// -// It is unsafe to modify the outgoing HTTP request at or past this hook, since -// doing so may invalidate the signature of the request. -// -// Available InterceptorContext fields: -// - Input -// - Request -type AfterSigningInterceptor interface { - AfterSigning(ctx context.Context, in *InterceptorContext) error -} - -// BeforeTransmitInterceptor runs right before the HTTP request is sent. -// -// HTTP transmit occurs within the operation's retry loop. -// -// Available InterceptorContext fields: -// - Input -// - Request -type BeforeTransmitInterceptor interface { - BeforeTransmit(ctx context.Context, in *InterceptorContext) error -} - -// AfterTransmitInterceptor runs right after the HTTP response is received. -// -// It will always be invoked when a response is received, regardless of its -// status code. Conversely, it WILL NOT be invoked if the HTTP round-trip was -// not successful, e.g. because of a DNS resolution error -// -// Available InterceptorContext fields: -// - Input -// - Request -// - Response -type AfterTransmitInterceptor interface { - AfterTransmit(ctx context.Context, in *InterceptorContext) error -} - -// BeforeDeserializationInterceptor runs right before the incoming HTTP response -// is deserialized. -// -// This interceptor IS NOT invoked if the HTTP round-trip was not successful. -// -// Deserialization occurs within the operation's retry loop. -// -// Available InterceptorContext fields: -// - Input -// - Request -// - Response -type BeforeDeserializationInterceptor interface { - BeforeDeserialization(ctx context.Context, in *InterceptorContext) error -} - -// AfterDeserializationInterceptor runs right after the incoming HTTP response -// is deserialized. This hook is invoked regardless of whether the deserialized -// result was an error. -// -// This interceptor IS NOT invoked if the HTTP round-trip was not successful. -// -// Available InterceptorContext fields: -// - Input -// - Output (IF the operation had a success-level response) -// - Request -// - Response -type AfterDeserializationInterceptor interface { - AfterDeserialization(ctx context.Context, in *InterceptorContext) error -} - -// AfterAttemptInterceptor runs right after the incoming HTTP response -// is deserialized. This hook is invoked regardless of whether the deserialized -// result was an error, or if another interceptor within the retry loop -// returned an error. -// -// Available InterceptorContext fields: -// - Input -// - Output (IF the operation had a success-level response) -// - Request (IF the operation did not return an error during serialization) -// - Response (IF the operation was able to transmit the HTTP request) -type AfterAttemptInterceptor interface { - AfterAttempt(ctx context.Context, in *InterceptorContext) error -} - -// AfterExecutionInterceptor runs after everything else. It runs regardless of -// how far the operation progressed in its lifecycle, and regardless of whether -// the operation succeeded or failed. -// -// Available InterceptorContext fields: -// - Input -// - Output (IF the operation had a success-level response) -// - Request (IF the operation did not return an error during serialization) -// - Response (IF the operation was able to transmit the HTTP request) -type AfterExecutionInterceptor interface { - AfterExecution(ctx context.Context, in *InterceptorContext) error -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go b/vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go deleted file mode 100644 index 2cc4b57..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go +++ /dev/null @@ -1,325 +0,0 @@ -package http - -import ( - "context" - "errors" - - "github.com/aws/smithy-go/middleware" -) - -type ictxKey struct{} - -func withIctx(ctx context.Context) context.Context { - return middleware.WithStackValue(ctx, ictxKey{}, &InterceptorContext{}) -} - -func getIctx(ctx context.Context) *InterceptorContext { - return middleware.GetStackValue(ctx, ictxKey{}).(*InterceptorContext) -} - -// InterceptExecution runs Before/AfterExecutionInterceptors. -type InterceptExecution struct { - BeforeExecution []BeforeExecutionInterceptor - AfterExecution []AfterExecutionInterceptor -} - -// ID identifies the middleware. -func (m *InterceptExecution) ID() string { - return "InterceptExecution" -} - -// HandleInitialize runs the interceptors. -func (m *InterceptExecution) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - out middleware.InitializeOutput, md middleware.Metadata, err error, -) { - ctx = withIctx(ctx) - getIctx(ctx).Input = in.Parameters - - for _, i := range m.BeforeExecution { - if err := i.BeforeExecution(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - out, md, err = next.HandleInitialize(ctx, in) - - for _, i := range m.AfterExecution { - if err := i.AfterExecution(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return out, md, err -} - -// InterceptBeforeSerialization runs BeforeSerializationInterceptors. -type InterceptBeforeSerialization struct { - Interceptors []BeforeSerializationInterceptor -} - -// ID identifies the middleware. -func (m *InterceptBeforeSerialization) ID() string { - return "InterceptBeforeSerialization" -} - -// HandleSerialize runs the interceptors. -func (m *InterceptBeforeSerialization) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - out middleware.SerializeOutput, md middleware.Metadata, err error, -) { - for _, i := range m.Interceptors { - if err := i.BeforeSerialization(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return next.HandleSerialize(ctx, in) -} - -// InterceptAfterSerialization runs AfterSerializationInterceptors. -type InterceptAfterSerialization struct { - Interceptors []AfterSerializationInterceptor -} - -// ID identifies the middleware. -func (m *InterceptAfterSerialization) ID() string { - return "InterceptAfterSerialization" -} - -// HandleSerialize runs the interceptors. -func (m *InterceptAfterSerialization) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - out middleware.SerializeOutput, md middleware.Metadata, err error, -) { - getIctx(ctx).Request = in.Request.(*Request) - - for _, i := range m.Interceptors { - if err := i.AfterSerialization(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return next.HandleSerialize(ctx, in) -} - -// InterceptBeforeRetryLoop runs BeforeRetryLoopInterceptors. -type InterceptBeforeRetryLoop struct { - Interceptors []BeforeRetryLoopInterceptor -} - -// ID identifies the middleware. -func (m *InterceptBeforeRetryLoop) ID() string { - return "InterceptBeforeRetryLoop" -} - -// HandleFinalize runs the interceptors. -func (m *InterceptBeforeRetryLoop) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, md middleware.Metadata, err error, -) { - for _, i := range m.Interceptors { - if err := i.BeforeRetryLoop(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return next.HandleFinalize(ctx, in) -} - -// InterceptBeforeSigning runs BeforeSigningInterceptors. -type InterceptBeforeSigning struct { - Interceptors []BeforeSigningInterceptor -} - -// ID identifies the middleware. -func (m *InterceptBeforeSigning) ID() string { - return "InterceptBeforeSigning" -} - -// HandleFinalize runs the interceptors. -func (m *InterceptBeforeSigning) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, md middleware.Metadata, err error, -) { - for _, i := range m.Interceptors { - if err := i.BeforeSigning(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return next.HandleFinalize(ctx, in) -} - -// InterceptAfterSigning runs AfterSigningInterceptors. -type InterceptAfterSigning struct { - Interceptors []AfterSigningInterceptor -} - -// ID identifies the middleware. -func (m *InterceptAfterSigning) ID() string { - return "InterceptAfterSigning" -} - -// HandleFinalize runs the interceptors. -func (m *InterceptAfterSigning) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, md middleware.Metadata, err error, -) { - for _, i := range m.Interceptors { - if err := i.AfterSigning(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return next.HandleFinalize(ctx, in) -} - -// InterceptTransmit runs BeforeTransmitInterceptors and AfterTransmitInterceptors. -type InterceptTransmit struct { - BeforeTransmit []BeforeTransmitInterceptor - AfterTransmit []AfterTransmitInterceptor -} - -// ID identifies the middleware. -func (m *InterceptTransmit) ID() string { - return "InterceptTransmit" -} - -// HandleDeserialize runs the interceptors. -func (m *InterceptTransmit) HandleDeserialize( - ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - out middleware.DeserializeOutput, md middleware.Metadata, err error, -) { - for _, i := range m.BeforeTransmit { - if err := i.BeforeTransmit(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - out, md, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, md, err - } - - // the root of the decorated middleware guarantees this will be here - // (client.go: ClientHandler.Handle) - getIctx(ctx).Response = out.RawResponse.(*Response) - - for _, i := range m.AfterTransmit { - if err := i.AfterTransmit(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return out, md, err -} - -// InterceptBeforeDeserialization runs BeforeDeserializationInterceptors. -type InterceptBeforeDeserialization struct { - Interceptors []BeforeDeserializationInterceptor -} - -// ID identifies the middleware. -func (m *InterceptBeforeDeserialization) ID() string { - return "InterceptBeforeDeserialization" -} - -// HandleDeserialize runs the interceptors. -func (m *InterceptBeforeDeserialization) HandleDeserialize( - ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - out middleware.DeserializeOutput, md middleware.Metadata, err error, -) { - out, md, err = next.HandleDeserialize(ctx, in) - if err != nil { - var terr *RequestSendError - if errors.As(err, &terr) { - return out, md, err - } - } - - for _, i := range m.Interceptors { - if err := i.BeforeDeserialization(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return out, md, err -} - -// InterceptAfterDeserialization runs AfterDeserializationInterceptors. -type InterceptAfterDeserialization struct { - Interceptors []AfterDeserializationInterceptor -} - -// ID identifies the middleware. -func (m *InterceptAfterDeserialization) ID() string { - return "InterceptAfterDeserialization" -} - -// HandleDeserialize runs the interceptors. -func (m *InterceptAfterDeserialization) HandleDeserialize( - ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - out middleware.DeserializeOutput, md middleware.Metadata, err error, -) { - out, md, err = next.HandleDeserialize(ctx, in) - if err != nil { - var terr *RequestSendError - if errors.As(err, &terr) { - return out, md, err - } - } - - getIctx(ctx).Output = out.Result - - for _, i := range m.Interceptors { - if err := i.AfterDeserialization(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return out, md, err -} - -// InterceptAttempt runs AfterAttemptInterceptors. -type InterceptAttempt struct { - BeforeAttempt []BeforeAttemptInterceptor - AfterAttempt []AfterAttemptInterceptor -} - -// ID identifies the middleware. -func (m *InterceptAttempt) ID() string { - return "InterceptAttempt" -} - -// HandleFinalize runs the interceptors. -func (m *InterceptAttempt) HandleFinalize( - ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, -) ( - out middleware.FinalizeOutput, md middleware.Metadata, err error, -) { - for _, i := range m.BeforeAttempt { - if err := i.BeforeAttempt(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - out, md, err = next.HandleFinalize(ctx, in) - - for _, i := range m.AfterAttempt { - if err := i.AfterAttempt(ctx, getIctx(ctx)); err != nil { - return out, md, err - } - } - - return out, md, err -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/internal/io/safe.go b/vendor/github.com/aws/smithy-go/transport/http/internal/io/safe.go deleted file mode 100644 index 941a8d6..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/internal/io/safe.go +++ /dev/null @@ -1,75 +0,0 @@ -package io - -import ( - "io" - "sync" -) - -// NewSafeReadCloser returns a new safeReadCloser that wraps readCloser. -func NewSafeReadCloser(readCloser io.ReadCloser) io.ReadCloser { - sr := &safeReadCloser{ - readCloser: readCloser, - } - - if _, ok := readCloser.(io.WriterTo); ok { - return &safeWriteToReadCloser{safeReadCloser: sr} - } - - return sr -} - -// safeWriteToReadCloser wraps a safeReadCloser but exposes a WriteTo interface implementation. This will panic -// if the underlying io.ReadClose does not support WriteTo. Use NewSafeReadCloser to ensure the proper handling of this -// type. -type safeWriteToReadCloser struct { - *safeReadCloser -} - -// WriteTo implements the io.WriteTo interface. -func (r *safeWriteToReadCloser) WriteTo(w io.Writer) (int64, error) { - r.safeReadCloser.mtx.Lock() - defer r.safeReadCloser.mtx.Unlock() - - if r.safeReadCloser.closed { - return 0, io.EOF - } - - return r.safeReadCloser.readCloser.(io.WriterTo).WriteTo(w) -} - -// safeReadCloser wraps a io.ReadCloser and presents an io.ReadCloser interface. When Close is called on safeReadCloser -// the underlying Close method will be executed, and then the reference to the reader will be dropped. This type -// is meant to be used with the net/http library which will retain a reference to the request body for the lifetime -// of a goroutine connection. Wrapping in this manner will ensure that no data race conditions are falsely reported. -// This type is thread-safe. -type safeReadCloser struct { - readCloser io.ReadCloser - closed bool - mtx sync.Mutex -} - -// Read reads up to len(p) bytes into p from the underlying read. If the reader is closed io.EOF will be returned. -func (r *safeReadCloser) Read(p []byte) (n int, err error) { - r.mtx.Lock() - defer r.mtx.Unlock() - if r.closed { - return 0, io.EOF - } - - return r.readCloser.Read(p) -} - -// Close calls the underlying io.ReadCloser's Close method, removes the reference to the reader, and returns any error -// reported from Close. Subsequent calls to Close will always return a nil error. -func (r *safeReadCloser) Close() error { - r.mtx.Lock() - defer r.mtx.Unlock() - if r.closed { - return nil - } - - r.closed = true - rc := r.readCloser - r.readCloser = nil - return rc.Close() -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/md5_checksum.go b/vendor/github.com/aws/smithy-go/transport/http/md5_checksum.go deleted file mode 100644 index 5d6a4b2..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/md5_checksum.go +++ /dev/null @@ -1,25 +0,0 @@ -package http - -import ( - "crypto/md5" - "encoding/base64" - "fmt" - "io" -) - -// computeMD5Checksum computes base64 md5 checksum of an io.Reader's contents. -// Returns the byte slice of md5 checksum and an error. -func computeMD5Checksum(r io.Reader) ([]byte, error) { - h := md5.New() - // copy errors may be assumed to be from the body. - _, err := io.Copy(h, r) - if err != nil { - return nil, fmt.Errorf("failed to read body: %w", err) - } - - // encode the md5 checksum in base64. - sum := h.Sum(nil) - sum64 := make([]byte, base64.StdEncoding.EncodedLen(len(sum))) - base64.StdEncoding.Encode(sum64, sum) - return sum64, nil -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/metrics.go b/vendor/github.com/aws/smithy-go/transport/http/metrics.go deleted file mode 100644 index b4cd4a4..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/metrics.go +++ /dev/null @@ -1,204 +0,0 @@ -package http - -import ( - "context" - "crypto/tls" - "net/http" - "net/http/httptrace" - "sync/atomic" - "time" - - "github.com/aws/smithy-go/metrics" -) - -var now = time.Now - -// withMetrics instruments an HTTP client and context to collect HTTP metrics. -func withMetrics(parent context.Context, client ClientDo, meter metrics.Meter) ( - context.Context, ClientDo, error, -) { - // WithClientTrace is an expensive operation - avoid calling it if we're - // not actually using a metrics sink. - if _, ok := meter.(metrics.NopMeter); ok { - return parent, client, nil - } - - hm, err := newHTTPMetrics(meter) - if err != nil { - return nil, nil, err - } - - ctx := httptrace.WithClientTrace(parent, &httptrace.ClientTrace{ - DNSStart: hm.DNSStart, - ConnectStart: hm.ConnectStart, - TLSHandshakeStart: hm.TLSHandshakeStart, - - GotConn: hm.GotConn(parent), - PutIdleConn: hm.PutIdleConn(parent), - ConnectDone: hm.ConnectDone(parent), - DNSDone: hm.DNSDone(parent), - TLSHandshakeDone: hm.TLSHandshakeDone(parent), - GotFirstResponseByte: hm.GotFirstResponseByte(parent), - }) - return ctx, &timedClientDo{client, hm}, nil -} - -type timedClientDo struct { - ClientDo - hm *httpMetrics -} - -func (c *timedClientDo) Do(r *http.Request) (*http.Response, error) { - c.hm.doStart.Store(now()) - resp, err := c.ClientDo.Do(r) - - c.hm.DoRequestDuration.Record(r.Context(), c.hm.doStart.Elapsed()) - return resp, err -} - -type httpMetrics struct { - DNSLookupDuration metrics.Float64Histogram // client.http.connections.dns_lookup_duration - ConnectDuration metrics.Float64Histogram // client.http.connections.acquire_duration - TLSHandshakeDuration metrics.Float64Histogram // client.http.connections.tls_handshake_duration - ConnectionUsage metrics.Int64UpDownCounter // client.http.connections.usage - - DoRequestDuration metrics.Float64Histogram // client.http.do_request_duration - TimeToFirstByte metrics.Float64Histogram // client.http.time_to_first_byte - - doStart safeTime - dnsStart safeTime - connectStart safeTime - tlsStart safeTime -} - -func newHTTPMetrics(meter metrics.Meter) (*httpMetrics, error) { - hm := &httpMetrics{} - - var err error - hm.DNSLookupDuration, err = meter.Float64Histogram("client.http.connections.dns_lookup_duration", func(o *metrics.InstrumentOptions) { - o.UnitLabel = "s" - o.Description = "The time it takes a request to perform DNS lookup." - }) - if err != nil { - return nil, err - } - hm.ConnectDuration, err = meter.Float64Histogram("client.http.connections.acquire_duration", func(o *metrics.InstrumentOptions) { - o.UnitLabel = "s" - o.Description = "The time it takes a request to acquire a connection." - }) - if err != nil { - return nil, err - } - hm.TLSHandshakeDuration, err = meter.Float64Histogram("client.http.connections.tls_handshake_duration", func(o *metrics.InstrumentOptions) { - o.UnitLabel = "s" - o.Description = "The time it takes an HTTP request to perform the TLS handshake." - }) - if err != nil { - return nil, err - } - hm.ConnectionUsage, err = meter.Int64UpDownCounter("client.http.connections.usage", func(o *metrics.InstrumentOptions) { - o.UnitLabel = "{connection}" - o.Description = "Current state of connections pool." - }) - if err != nil { - return nil, err - } - hm.DoRequestDuration, err = meter.Float64Histogram("client.http.do_request_duration", func(o *metrics.InstrumentOptions) { - o.UnitLabel = "s" - o.Description = "Time spent performing an entire HTTP transaction." - }) - if err != nil { - return nil, err - } - hm.TimeToFirstByte, err = meter.Float64Histogram("client.http.time_to_first_byte", func(o *metrics.InstrumentOptions) { - o.UnitLabel = "s" - o.Description = "Time from start of transaction to when the first response byte is available." - }) - if err != nil { - return nil, err - } - - return hm, nil -} - -func (m *httpMetrics) DNSStart(httptrace.DNSStartInfo) { - m.dnsStart.Store(now()) -} - -func (m *httpMetrics) ConnectStart(string, string) { - m.connectStart.Store(now()) -} - -func (m *httpMetrics) TLSHandshakeStart() { - m.tlsStart.Store(now()) -} - -func (m *httpMetrics) GotConn(ctx context.Context) func(httptrace.GotConnInfo) { - return func(httptrace.GotConnInfo) { - m.addConnAcquired(ctx, 1) - } -} - -func (m *httpMetrics) PutIdleConn(ctx context.Context) func(error) { - return func(error) { - m.addConnAcquired(ctx, -1) - } -} - -func (m *httpMetrics) DNSDone(ctx context.Context) func(httptrace.DNSDoneInfo) { - return func(httptrace.DNSDoneInfo) { - m.DNSLookupDuration.Record(ctx, m.dnsStart.Elapsed()) - } -} - -func (m *httpMetrics) ConnectDone(ctx context.Context) func(string, string, error) { - return func(string, string, error) { - m.ConnectDuration.Record(ctx, m.connectStart.Elapsed()) - } -} - -func (m *httpMetrics) TLSHandshakeDone(ctx context.Context) func(tls.ConnectionState, error) { - return func(tls.ConnectionState, error) { - m.TLSHandshakeDuration.Record(ctx, m.tlsStart.Elapsed()) - } -} - -func (m *httpMetrics) GotFirstResponseByte(ctx context.Context) func() { - return func() { - m.TimeToFirstByte.Record(ctx, m.doStart.Elapsed()) - } -} - -func (m *httpMetrics) addConnAcquired(ctx context.Context, incr int64) { - m.ConnectionUsage.Add(ctx, incr, func(o *metrics.RecordMetricOptions) { - o.Properties.Set("state", "acquired") - }) -} - -// Not used: it is recommended to track acquired vs idle conn, but we can't -// determine when something is truly idle with the current HTTP client hooks -// available to us. -func (m *httpMetrics) addConnIdle(ctx context.Context, incr int64) { - m.ConnectionUsage.Add(ctx, incr, func(o *metrics.RecordMetricOptions) { - o.Properties.Set("state", "idle") - }) -} - -type safeTime struct { - atomic.Value // time.Time -} - -func (st *safeTime) Store(v time.Time) { - st.Value.Store(v) -} - -func (st *safeTime) Load() time.Time { - t, _ := st.Value.Load().(time.Time) - return t -} - -func (st *safeTime) Elapsed() float64 { - end := now() - elapsed := end.Sub(st.Load()) - return float64(elapsed) / 1e9 -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_close_response_body.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_close_response_body.go deleted file mode 100644 index 914338f..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_close_response_body.go +++ /dev/null @@ -1,79 +0,0 @@ -package http - -import ( - "context" - "io" - - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" -) - -// AddErrorCloseResponseBodyMiddleware adds the middleware to automatically -// close the response body of an operation request if the request response -// failed. -func AddErrorCloseResponseBodyMiddleware(stack *middleware.Stack) error { - return stack.Deserialize.Insert(&errorCloseResponseBodyMiddleware{}, "OperationDeserializer", middleware.Before) -} - -type errorCloseResponseBodyMiddleware struct{} - -func (*errorCloseResponseBodyMiddleware) ID() string { - return "ErrorCloseResponseBody" -} - -func (m *errorCloseResponseBodyMiddleware) HandleDeserialize( - ctx context.Context, input middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - output middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err := next.HandleDeserialize(ctx, input) - if err != nil { - if resp, ok := out.RawResponse.(*Response); ok && resp != nil && resp.Body != nil { - // Consume the full body to prevent TCP connection resets on some platforms - _, _ = io.Copy(io.Discard, resp.Body) - // Do not validate that the response closes successfully. - resp.Body.Close() - } - } - - return out, metadata, err -} - -// AddCloseResponseBodyMiddleware adds the middleware to automatically close -// the response body of an operation request, after the response had been -// deserialized. -func AddCloseResponseBodyMiddleware(stack *middleware.Stack) error { - return stack.Deserialize.Insert(&closeResponseBody{}, "OperationDeserializer", middleware.Before) -} - -type closeResponseBody struct{} - -func (*closeResponseBody) ID() string { - return "CloseResponseBody" -} - -func (m *closeResponseBody) HandleDeserialize( - ctx context.Context, input middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - output middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err := next.HandleDeserialize(ctx, input) - if err != nil { - return out, metadata, err - } - - if resp, ok := out.RawResponse.(*Response); ok { - // Consume the full body to prevent TCP connection resets on some platforms - _, copyErr := io.Copy(io.Discard, resp.Body) - if copyErr != nil { - middleware.GetLogger(ctx).Logf(logging.Warn, "failed to discard remaining HTTP response body, this may affect connection reuse") - } - - closeErr := resp.Body.Close() - if closeErr != nil { - middleware.GetLogger(ctx).Logf(logging.Warn, "failed to close HTTP response body, this may affect connection reuse") - } - } - - return out, metadata, err -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go deleted file mode 100644 index 9969389..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go +++ /dev/null @@ -1,84 +0,0 @@ -package http - -import ( - "context" - "fmt" - - "github.com/aws/smithy-go/middleware" -) - -// ComputeContentLength provides a middleware to set the content-length -// header for the length of a serialize request body. -type ComputeContentLength struct { -} - -// AddComputeContentLengthMiddleware adds ComputeContentLength to the middleware -// stack's Build step. -func AddComputeContentLengthMiddleware(stack *middleware.Stack) error { - return stack.Build.Add(&ComputeContentLength{}, middleware.After) -} - -// ID returns the identifier for the ComputeContentLength. -func (m *ComputeContentLength) ID() string { return "ComputeContentLength" } - -// HandleBuild adds the length of the serialized request to the HTTP header -// if the length can be determined. -func (m *ComputeContentLength) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*Request) - if !ok { - return out, metadata, fmt.Errorf("unknown request type %T", req) - } - - // do nothing if request content-length was set to 0 or above. - if req.ContentLength >= 0 { - return next.HandleBuild(ctx, in) - } - - // attempt to compute stream length - if n, ok, err := req.StreamLength(); err != nil { - return out, metadata, fmt.Errorf( - "failed getting length of request stream, %w", err) - } else if ok { - req.ContentLength = n - } - - return next.HandleBuild(ctx, in) -} - -// validateContentLength provides a middleware to validate the content-length -// is valid (greater than zero), for the serialized request payload. -type validateContentLength struct{} - -// ValidateContentLengthHeader adds middleware that validates request content-length -// is set to value greater than zero. -func ValidateContentLengthHeader(stack *middleware.Stack) error { - return stack.Build.Add(&validateContentLength{}, middleware.After) -} - -// ID returns the identifier for the ComputeContentLength. -func (m *validateContentLength) ID() string { return "ValidateContentLength" } - -// HandleBuild adds the length of the serialized request to the HTTP header -// if the length can be determined. -func (m *validateContentLength) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - req, ok := in.Request.(*Request) - if !ok { - return out, metadata, fmt.Errorf("unknown request type %T", req) - } - - // if request content-length was set to less than 0, return an error - if req.ContentLength < 0 { - return out, metadata, fmt.Errorf( - "content length for payload is required and must be at least 0") - } - - return next.HandleBuild(ctx, in) -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_header_comment.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_header_comment.go deleted file mode 100644 index 855c227..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_header_comment.go +++ /dev/null @@ -1,81 +0,0 @@ -package http - -import ( - "context" - "fmt" - "net/http" - - "github.com/aws/smithy-go/middleware" -) - -// WithHeaderComment instruments a middleware stack to append an HTTP field -// comment to the given header as specified in RFC 9110 -// (https://www.rfc-editor.org/rfc/rfc9110#name-comments). -// -// The header is case-insensitive. If the provided header exists when the -// middleware runs, the content will be inserted as-is enclosed in parentheses. -// -// Note that per the HTTP specification, comments are only allowed in fields -// containing "comment" as part of their field value definition, but this API -// will NOT verify whether the provided header is one of them. -// -// WithHeaderComment MAY be applied more than once to a middleware stack and/or -// more than once per header. -func WithHeaderComment(header, content string) func(*middleware.Stack) error { - return func(s *middleware.Stack) error { - m, err := getOrAddHeaderComment(s) - if err != nil { - return fmt.Errorf("get or add header comment: %v", err) - } - - m.values.Add(header, content) - return nil - } -} - -type headerCommentMiddleware struct { - values http.Header // hijack case-insensitive access APIs -} - -func (*headerCommentMiddleware) ID() string { - return "headerComment" -} - -func (m *headerCommentMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( - out middleware.BuildOutput, metadata middleware.Metadata, err error, -) { - r, ok := in.Request.(*Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - for h, contents := range m.values { - for _, c := range contents { - if existing := r.Header.Get(h); existing != "" { - r.Header.Set(h, fmt.Sprintf("%s (%s)", existing, c)) - } - } - } - - return next.HandleBuild(ctx, in) -} - -func getOrAddHeaderComment(s *middleware.Stack) (*headerCommentMiddleware, error) { - id := (*headerCommentMiddleware)(nil).ID() - m, ok := s.Build.Get(id) - if !ok { - m := &headerCommentMiddleware{values: http.Header{}} - if err := s.Build.Add(m, middleware.After); err != nil { - return nil, fmt.Errorf("add build: %v", err) - } - - return m, nil - } - - hc, ok := m.(*headerCommentMiddleware) - if !ok { - return nil, fmt.Errorf("existing middleware w/ id %s is not *headerCommentMiddleware", id) - } - - return hc, nil -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_headers.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_headers.go deleted file mode 100644 index eac32b4..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_headers.go +++ /dev/null @@ -1,167 +0,0 @@ -package http - -import ( - "context" - "fmt" - - "github.com/aws/smithy-go/middleware" -) - -type isContentTypeAutoSet struct{} - -// SetIsContentTypeDefaultValue returns a Context specifying if the request's -// content-type header was set to a default value. -func SetIsContentTypeDefaultValue(ctx context.Context, isDefault bool) context.Context { - return context.WithValue(ctx, isContentTypeAutoSet{}, isDefault) -} - -// GetIsContentTypeDefaultValue returns if the content-type HTTP header on the -// request is a default value that was auto assigned by an operation -// serializer. Allows middleware post serialization to know if the content-type -// was auto set to a default value or not. -// -// Also returns false if the Context value was never updated to include if -// content-type was set to a default value. -func GetIsContentTypeDefaultValue(ctx context.Context) bool { - v, _ := ctx.Value(isContentTypeAutoSet{}).(bool) - return v -} - -// AddNoPayloadDefaultContentTypeRemover Adds the DefaultContentTypeRemover -// middleware to the stack after the operation serializer. This middleware will -// remove the content-type header from the request if it was set as a default -// value, and no request payload is present. -// -// Returns error if unable to add the middleware. -func AddNoPayloadDefaultContentTypeRemover(stack *middleware.Stack) (err error) { - err = stack.Serialize.Insert(removeDefaultContentType{}, - "OperationSerializer", middleware.After) - if err != nil { - return fmt.Errorf("failed to add %s serialize middleware, %w", - removeDefaultContentType{}.ID(), err) - } - - return nil -} - -// RemoveNoPayloadDefaultContentTypeRemover removes the -// DefaultContentTypeRemover middleware from the stack. Returns an error if -// unable to remove the middleware. -func RemoveNoPayloadDefaultContentTypeRemover(stack *middleware.Stack) (err error) { - _, err = stack.Serialize.Remove(removeDefaultContentType{}.ID()) - if err != nil { - return fmt.Errorf("failed to remove %s serialize middleware, %w", - removeDefaultContentType{}.ID(), err) - - } - return nil -} - -// removeDefaultContentType provides after serialization middleware that will -// remove the content-type header from an HTTP request if the header was set as -// a default value by the operation serializer, and there is no request payload. -type removeDefaultContentType struct{} - -// ID returns the middleware ID -func (removeDefaultContentType) ID() string { return "RemoveDefaultContentType" } - -// HandleSerialize implements the serialization middleware. -func (removeDefaultContentType) HandleSerialize( - ctx context.Context, input middleware.SerializeInput, next middleware.SerializeHandler, -) ( - out middleware.SerializeOutput, meta middleware.Metadata, err error, -) { - req, ok := input.Request.(*Request) - if !ok { - return out, meta, fmt.Errorf( - "unexpected request type %T for removeDefaultContentType middleware", - input.Request) - } - - if GetIsContentTypeDefaultValue(ctx) && req.GetStream() == nil { - req.Header.Del("Content-Type") - input.Request = req - } - - return next.HandleSerialize(ctx, input) -} - -type headerValue struct { - header string - value string - append bool -} - -type headerValueHelper struct { - headerValues []headerValue -} - -func (h *headerValueHelper) addHeaderValue(value headerValue) { - h.headerValues = append(h.headerValues, value) -} - -func (h *headerValueHelper) ID() string { - return "HTTPHeaderHelper" -} - -func (h *headerValueHelper) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) (out middleware.BuildOutput, metadata middleware.Metadata, err error) { - req, ok := in.Request.(*Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) - } - - for _, value := range h.headerValues { - if value.append { - req.Header.Add(value.header, value.value) - } else { - req.Header.Set(value.header, value.value) - } - } - - return next.HandleBuild(ctx, in) -} - -func getOrAddHeaderValueHelper(stack *middleware.Stack) (*headerValueHelper, error) { - id := (*headerValueHelper)(nil).ID() - m, ok := stack.Build.Get(id) - if !ok { - m = &headerValueHelper{} - err := stack.Build.Add(m, middleware.After) - if err != nil { - return nil, err - } - } - - requestUserAgent, ok := m.(*headerValueHelper) - if !ok { - return nil, fmt.Errorf("%T for %s middleware did not match expected type", m, id) - } - - return requestUserAgent, nil -} - -// AddHeaderValue returns a stack mutator that adds the header value pair to header. -// Appends to any existing values if present. -func AddHeaderValue(header string, value string) func(stack *middleware.Stack) error { - return func(stack *middleware.Stack) error { - helper, err := getOrAddHeaderValueHelper(stack) - if err != nil { - return err - } - helper.addHeaderValue(headerValue{header: header, value: value, append: true}) - return nil - } -} - -// SetHeaderValue returns a stack mutator that adds the header value pair to header. -// Replaces any existing values if present. -func SetHeaderValue(header string, value string) func(stack *middleware.Stack) error { - return func(stack *middleware.Stack) error { - helper, err := getOrAddHeaderValueHelper(stack) - if err != nil { - return err - } - helper.addHeaderValue(headerValue{header: header, value: value, append: false}) - return nil - } -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_http_logging.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_http_logging.go deleted file mode 100644 index d5909b0..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_http_logging.go +++ /dev/null @@ -1,75 +0,0 @@ -package http - -import ( - "context" - "fmt" - "net/http/httputil" - - "github.com/aws/smithy-go/logging" - "github.com/aws/smithy-go/middleware" -) - -// RequestResponseLogger is a deserialize middleware that will log the request and response HTTP messages and optionally -// their respective bodies. Will not perform any logging if none of the options are set. -type RequestResponseLogger struct { - LogRequest bool - LogRequestWithBody bool - - LogResponse bool - LogResponseWithBody bool -} - -// ID is the middleware identifier. -func (r *RequestResponseLogger) ID() string { - return "RequestResponseLogger" -} - -// HandleDeserialize will log the request and response HTTP messages if configured accordingly. -func (r *RequestResponseLogger) HandleDeserialize( - ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - logger := middleware.GetLogger(ctx) - - if r.LogRequest || r.LogRequestWithBody { - smithyRequest, ok := in.Request.(*Request) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", in) - } - - rc := smithyRequest.Build(ctx) - reqBytes, err := httputil.DumpRequestOut(rc, r.LogRequestWithBody) - if err != nil { - return out, metadata, err - } - - logger.Logf(logging.Debug, "Request\n%v", string(reqBytes)) - - if r.LogRequestWithBody { - smithyRequest, err = smithyRequest.SetStream(rc.Body) - if err != nil { - return out, metadata, err - } - in.Request = smithyRequest - } - } - - out, metadata, err = next.HandleDeserialize(ctx, in) - - if (err == nil) && (r.LogResponse || r.LogResponseWithBody) { - smithyResponse, ok := out.RawResponse.(*Response) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type %T", out.RawResponse) - } - - respBytes, err := httputil.DumpResponse(smithyResponse.Response, r.LogResponseWithBody) - if err != nil { - return out, metadata, fmt.Errorf("failed to dump response %w", err) - } - - logger.Logf(logging.Debug, "Response\n%v", string(respBytes)) - } - - return out, metadata, err -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_metadata.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_metadata.go deleted file mode 100644 index d6079b2..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_metadata.go +++ /dev/null @@ -1,51 +0,0 @@ -package http - -import ( - "context" - - "github.com/aws/smithy-go/middleware" -) - -type ( - hostnameImmutableKey struct{} - hostPrefixDisableKey struct{} -) - -// GetHostnameImmutable retrieves whether the endpoint hostname should be considered -// immutable or not. -// -// Scoped to stack values. Use middleware#ClearStackValues to clear all stack -// values. -func GetHostnameImmutable(ctx context.Context) (v bool) { - v, _ = middleware.GetStackValue(ctx, hostnameImmutableKey{}).(bool) - return v -} - -// SetHostnameImmutable sets or modifies whether the request's endpoint hostname -// should be considered immutable or not. -// -// Scoped to stack values. Use middleware#ClearStackValues to clear all stack -// values. -func SetHostnameImmutable(ctx context.Context, value bool) context.Context { - return middleware.WithStackValue(ctx, hostnameImmutableKey{}, value) -} - -// IsEndpointHostPrefixDisabled retrieves whether the hostname prefixing is -// disabled. -// -// Scoped to stack values. Use middleware#ClearStackValues to clear all stack -// values. -func IsEndpointHostPrefixDisabled(ctx context.Context) (v bool) { - v, _ = middleware.GetStackValue(ctx, hostPrefixDisableKey{}).(bool) - return v -} - -// DisableEndpointHostPrefix sets or modifies whether the request's endpoint host -// prefixing should be disabled. If value is true, endpoint host prefixing -// will be disabled. -// -// Scoped to stack values. Use middleware#ClearStackValues to clear all stack -// values. -func DisableEndpointHostPrefix(ctx context.Context, value bool) context.Context { - return middleware.WithStackValue(ctx, hostPrefixDisableKey{}, value) -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/middleware_min_proto.go b/vendor/github.com/aws/smithy-go/transport/http/middleware_min_proto.go deleted file mode 100644 index 326cb8a..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/middleware_min_proto.go +++ /dev/null @@ -1,79 +0,0 @@ -package http - -import ( - "context" - "fmt" - "github.com/aws/smithy-go/middleware" - "strings" -) - -// MinimumProtocolError is an error type indicating that the established connection did not meet the expected minimum -// HTTP protocol version. -type MinimumProtocolError struct { - proto string - expectedProtoMajor int - expectedProtoMinor int -} - -// Error returns the error message. -func (m *MinimumProtocolError) Error() string { - return fmt.Sprintf("operation requires minimum HTTP protocol of HTTP/%d.%d, but was %s", - m.expectedProtoMajor, m.expectedProtoMinor, m.proto) -} - -// RequireMinimumProtocol is a deserialization middleware that asserts that the established HTTP connection -// meets the minimum major ad minor version. -type RequireMinimumProtocol struct { - ProtoMajor int - ProtoMinor int -} - -// AddRequireMinimumProtocol adds the RequireMinimumProtocol middleware to the stack using the provided minimum -// protocol major and minor version. -func AddRequireMinimumProtocol(stack *middleware.Stack, major, minor int) error { - return stack.Deserialize.Insert(&RequireMinimumProtocol{ - ProtoMajor: major, - ProtoMinor: minor, - }, "OperationDeserializer", middleware.Before) -} - -// ID returns the middleware identifier string. -func (r *RequireMinimumProtocol) ID() string { - return "RequireMinimumProtocol" -} - -// HandleDeserialize asserts that the established connection is a HTTP connection with the minimum major and minor -// protocol version. -func (r *RequireMinimumProtocol) HandleDeserialize( - ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, -) ( - out middleware.DeserializeOutput, metadata middleware.Metadata, err error, -) { - out, metadata, err = next.HandleDeserialize(ctx, in) - if err != nil { - return out, metadata, err - } - - response, ok := out.RawResponse.(*Response) - if !ok { - return out, metadata, fmt.Errorf("unknown transport type: %T", out.RawResponse) - } - - if !strings.HasPrefix(response.Proto, "HTTP") { - return out, metadata, &MinimumProtocolError{ - proto: response.Proto, - expectedProtoMajor: r.ProtoMajor, - expectedProtoMinor: r.ProtoMinor, - } - } - - if response.ProtoMajor < r.ProtoMajor || response.ProtoMinor < r.ProtoMinor { - return out, metadata, &MinimumProtocolError{ - proto: response.Proto, - expectedProtoMajor: r.ProtoMajor, - expectedProtoMinor: r.ProtoMinor, - } - } - - return out, metadata, err -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/properties.go b/vendor/github.com/aws/smithy-go/transport/http/properties.go deleted file mode 100644 index c65aa39..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/properties.go +++ /dev/null @@ -1,80 +0,0 @@ -package http - -import smithy "github.com/aws/smithy-go" - -type ( - sigV4SigningNameKey struct{} - sigV4SigningRegionKey struct{} - - sigV4ASigningNameKey struct{} - sigV4ASigningRegionsKey struct{} - - isUnsignedPayloadKey struct{} - disableDoubleEncodingKey struct{} -) - -// GetSigV4SigningName gets the signing name from Properties. -func GetSigV4SigningName(p *smithy.Properties) (string, bool) { - v, ok := p.Get(sigV4SigningNameKey{}).(string) - return v, ok -} - -// SetSigV4SigningName sets the signing name on Properties. -func SetSigV4SigningName(p *smithy.Properties, name string) { - p.Set(sigV4SigningNameKey{}, name) -} - -// GetSigV4SigningRegion gets the signing region from Properties. -func GetSigV4SigningRegion(p *smithy.Properties) (string, bool) { - v, ok := p.Get(sigV4SigningRegionKey{}).(string) - return v, ok -} - -// SetSigV4SigningRegion sets the signing region on Properties. -func SetSigV4SigningRegion(p *smithy.Properties, region string) { - p.Set(sigV4SigningRegionKey{}, region) -} - -// GetSigV4ASigningName gets the v4a signing name from Properties. -func GetSigV4ASigningName(p *smithy.Properties) (string, bool) { - v, ok := p.Get(sigV4ASigningNameKey{}).(string) - return v, ok -} - -// SetSigV4ASigningName sets the signing name on Properties. -func SetSigV4ASigningName(p *smithy.Properties, name string) { - p.Set(sigV4ASigningNameKey{}, name) -} - -// GetSigV4ASigningRegion gets the v4a signing region set from Properties. -func GetSigV4ASigningRegions(p *smithy.Properties) ([]string, bool) { - v, ok := p.Get(sigV4ASigningRegionsKey{}).([]string) - return v, ok -} - -// SetSigV4ASigningRegions sets the v4a signing region set on Properties. -func SetSigV4ASigningRegions(p *smithy.Properties, regions []string) { - p.Set(sigV4ASigningRegionsKey{}, regions) -} - -// GetIsUnsignedPayload gets whether the payload is unsigned from Properties. -func GetIsUnsignedPayload(p *smithy.Properties) (bool, bool) { - v, ok := p.Get(isUnsignedPayloadKey{}).(bool) - return v, ok -} - -// SetIsUnsignedPayload sets whether the payload is unsigned on Properties. -func SetIsUnsignedPayload(p *smithy.Properties, isUnsignedPayload bool) { - p.Set(isUnsignedPayloadKey{}, isUnsignedPayload) -} - -// GetDisableDoubleEncoding gets whether the payload is unsigned from Properties. -func GetDisableDoubleEncoding(p *smithy.Properties) (bool, bool) { - v, ok := p.Get(disableDoubleEncodingKey{}).(bool) - return v, ok -} - -// SetDisableDoubleEncoding sets whether the payload is unsigned on Properties. -func SetDisableDoubleEncoding(p *smithy.Properties, disableDoubleEncoding bool) { - p.Set(disableDoubleEncodingKey{}, disableDoubleEncoding) -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/request.go b/vendor/github.com/aws/smithy-go/transport/http/request.go deleted file mode 100644 index 5cbf6f1..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/request.go +++ /dev/null @@ -1,188 +0,0 @@ -package http - -import ( - "context" - "fmt" - "io" - "net/http" - "net/url" - "strings" - - iointernal "github.com/aws/smithy-go/transport/http/internal/io" -) - -// Request provides the HTTP specific request structure for HTTP specific -// middleware steps to use to serialize input, and send an operation's request. -type Request struct { - *http.Request - stream io.Reader - isStreamSeekable bool - streamStartPos int64 -} - -// NewStackRequest returns an initialized request ready to be populated with the -// HTTP request details. Returns empty interface so the function can be used as -// a parameter to the Smithy middleware Stack constructor. -func NewStackRequest() interface{} { - return &Request{ - Request: &http.Request{ - URL: &url.URL{}, - Header: http.Header{}, - ContentLength: -1, // default to unknown length - }, - } -} - -// IsHTTPS returns if the request is HTTPS. Returns false if no endpoint URL is set. -func (r *Request) IsHTTPS() bool { - if r.URL == nil { - return false - } - return strings.EqualFold(r.URL.Scheme, "https") -} - -// Clone returns a deep copy of the Request for the new context. A reference to -// the Stream is copied, but the underlying stream is not copied. -func (r *Request) Clone() *Request { - rc := *r - rc.Request = rc.Request.Clone(context.TODO()) - return &rc -} - -// StreamLength returns the number of bytes of the serialized stream attached -// to the request and ok set. If the length cannot be determined, an error will -// be returned. -func (r *Request) StreamLength() (size int64, ok bool, err error) { - return streamLength(r.stream, r.isStreamSeekable, r.streamStartPos) -} - -func streamLength(stream io.Reader, seekable bool, startPos int64) (size int64, ok bool, err error) { - if stream == nil { - return 0, true, nil - } - - if l, ok := stream.(interface{ Len() int }); ok { - return int64(l.Len()), true, nil - } - - if !seekable { - return 0, false, nil - } - - s := stream.(io.Seeker) - endOffset, err := s.Seek(0, io.SeekEnd) - if err != nil { - return 0, false, err - } - - // The reason to seek to streamStartPos instead of 0 is to ensure that the - // SDK only sends the stream from the starting position the user's - // application provided it to the SDK at. For example application opens a - // file, and wants to skip the first N bytes uploading the rest. The - // application would move the file's offset N bytes, then hand it off to - // the SDK to send the remaining. The SDK should respect that initial offset. - _, err = s.Seek(startPos, io.SeekStart) - if err != nil { - return 0, false, err - } - - return endOffset - startPos, true, nil -} - -// RewindStream will rewind the io.Reader to the relative start position if it -// is an io.Seeker. -func (r *Request) RewindStream() error { - // If there is no stream there is nothing to rewind. - if r.stream == nil { - return nil - } - - if !r.isStreamSeekable { - return fmt.Errorf("request stream is not seekable") - } - _, err := r.stream.(io.Seeker).Seek(r.streamStartPos, io.SeekStart) - return err -} - -// GetStream returns the request stream io.Reader if a stream is set. If no -// stream is present nil will be returned. -func (r *Request) GetStream() io.Reader { - return r.stream -} - -// IsStreamSeekable returns whether the stream is seekable. -func (r *Request) IsStreamSeekable() bool { - return r.isStreamSeekable -} - -// SetStream returns a clone of the request with the stream set to the provided -// reader. May return an error if the provided reader is seekable but returns -// an error. -func (r *Request) SetStream(reader io.Reader) (rc *Request, err error) { - rc = r.Clone() - - if reader == http.NoBody { - reader = nil - } - - var isStreamSeekable bool - var streamStartPos int64 - switch v := reader.(type) { - case io.Seeker: - n, err := v.Seek(0, io.SeekCurrent) - if err != nil { - return r, err - } - isStreamSeekable = true - streamStartPos = n - default: - // If the stream length can be determined, and is determined to be empty, - // use a nil stream to prevent confusion between empty vs not-empty - // streams. - length, ok, err := streamLength(reader, false, 0) - if err != nil { - return nil, err - } else if ok && length == 0 { - reader = nil - } - } - - rc.stream = reader - rc.isStreamSeekable = isStreamSeekable - rc.streamStartPos = streamStartPos - - return rc, err -} - -// Build returns a build standard HTTP request value from the Smithy request. -// The request's stream is wrapped in a safe container that allows it to be -// reused for subsequent attempts. -func (r *Request) Build(ctx context.Context) *http.Request { - req := r.Request.Clone(ctx) - - if r.stream == nil && req.ContentLength == -1 { - req.ContentLength = 0 - } - - switch stream := r.stream.(type) { - case *io.PipeReader: - req.Body = io.NopCloser(stream) - req.ContentLength = -1 - default: - // HTTP Client Request must only have a non-nil body if the - // ContentLength is explicitly unknown (-1) or non-zero. The HTTP - // Client will interpret a non-nil body and ContentLength 0 as - // "unknown". This is unwanted behavior. - if req.ContentLength != 0 && r.stream != nil { - req.Body = iointernal.NewSafeReadCloser(io.NopCloser(stream)) - } - } - - return req -} - -// RequestCloner is a function that can take an input request type and clone the request -// for use in a subsequent retry attempt. -func RequestCloner(v interface{}) interface{} { - return v.(*Request).Clone() -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/response.go b/vendor/github.com/aws/smithy-go/transport/http/response.go deleted file mode 100644 index 0c13bfc..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/response.go +++ /dev/null @@ -1,34 +0,0 @@ -package http - -import ( - "fmt" - "net/http" -) - -// Response provides the HTTP specific response structure for HTTP specific -// middleware steps to use to deserialize the response from an operation call. -type Response struct { - *http.Response -} - -// ResponseError provides the HTTP centric error type wrapping the underlying -// error with the HTTP response value. -type ResponseError struct { - Response *Response - Err error -} - -// HTTPStatusCode returns the HTTP response status code received from the service. -func (e *ResponseError) HTTPStatusCode() int { return e.Response.StatusCode } - -// HTTPResponse returns the HTTP response received from the service. -func (e *ResponseError) HTTPResponse() *Response { return e.Response } - -// Unwrap returns the nested error if any, or nil. -func (e *ResponseError) Unwrap() error { return e.Err } - -func (e *ResponseError) Error() string { - return fmt.Sprintf( - "http response error StatusCode: %d, %v", - e.Response.StatusCode, e.Err) -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/time.go b/vendor/github.com/aws/smithy-go/transport/http/time.go deleted file mode 100644 index 607b196..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/time.go +++ /dev/null @@ -1,13 +0,0 @@ -package http - -import ( - "time" - - smithytime "github.com/aws/smithy-go/time" -) - -// ParseTime parses a time string like the HTTP Date header. This uses a more -// relaxed rule set for date parsing compared to the standard library. -func ParseTime(text string) (t time.Time, err error) { - return smithytime.ParseHTTPDate(text) -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/url.go b/vendor/github.com/aws/smithy-go/transport/http/url.go deleted file mode 100644 index 60a5fc1..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/url.go +++ /dev/null @@ -1,44 +0,0 @@ -package http - -import "strings" - -// JoinPath returns an absolute URL path composed of the two paths provided. -// Enforces that the returned path begins with '/'. If added path is empty the -// returned path suffix will match the first parameter suffix. -func JoinPath(a, b string) string { - if len(a) == 0 { - a = "/" - } else if a[0] != '/' { - a = "/" + a - } - - if len(b) != 0 && b[0] == '/' { - b = b[1:] - } - - if len(b) != 0 && len(a) > 1 && a[len(a)-1] != '/' { - a = a + "/" - } - - return a + b -} - -// JoinRawQuery returns an absolute raw query expression. Any duplicate '&' -// will be collapsed to single separator between values. -func JoinRawQuery(a, b string) string { - a = strings.TrimFunc(a, isAmpersand) - b = strings.TrimFunc(b, isAmpersand) - - if len(a) == 0 { - return b - } - if len(b) == 0 { - return a - } - - return a + "&" + b -} - -func isAmpersand(v rune) bool { - return v == '&' -} diff --git a/vendor/github.com/aws/smithy-go/transport/http/user_agent.go b/vendor/github.com/aws/smithy-go/transport/http/user_agent.go deleted file mode 100644 index 71a7e0d..0000000 --- a/vendor/github.com/aws/smithy-go/transport/http/user_agent.go +++ /dev/null @@ -1,37 +0,0 @@ -package http - -import ( - "strings" -) - -// UserAgentBuilder is a builder for a HTTP User-Agent string. -type UserAgentBuilder struct { - sb strings.Builder -} - -// NewUserAgentBuilder returns a new UserAgentBuilder. -func NewUserAgentBuilder() *UserAgentBuilder { - return &UserAgentBuilder{sb: strings.Builder{}} -} - -// AddKey adds the named component/product to the agent string -func (u *UserAgentBuilder) AddKey(key string) { - u.appendTo(key) -} - -// AddKeyValue adds the named key to the agent string with the given value. -func (u *UserAgentBuilder) AddKeyValue(key, value string) { - u.appendTo(key + "/" + value) -} - -// Build returns the constructed User-Agent string. May be called multiple times. -func (u *UserAgentBuilder) Build() string { - return u.sb.String() -} - -func (u *UserAgentBuilder) appendTo(value string) { - if u.sb.Len() > 0 { - u.sb.WriteRune(' ') - } - u.sb.WriteString(value) -} diff --git a/vendor/github.com/aws/smithy-go/validation.go b/vendor/github.com/aws/smithy-go/validation.go deleted file mode 100644 index b5eedc1..0000000 --- a/vendor/github.com/aws/smithy-go/validation.go +++ /dev/null @@ -1,140 +0,0 @@ -package smithy - -import ( - "bytes" - "fmt" - "strings" -) - -// An InvalidParamsError provides wrapping of invalid parameter errors found when -// validating API operation input parameters. -type InvalidParamsError struct { - // Context is the base context of the invalid parameter group. - Context string - errs []InvalidParamError -} - -// Add adds a new invalid parameter error to the collection of invalid -// parameters. The context of the invalid parameter will be updated to reflect -// this collection. -func (e *InvalidParamsError) Add(err InvalidParamError) { - err.SetContext(e.Context) - e.errs = append(e.errs, err) -} - -// AddNested adds the invalid parameter errors from another InvalidParamsError -// value into this collection. The nested errors will have their nested context -// updated and base context to reflect the merging. -// -// Use for nested validations errors. -func (e *InvalidParamsError) AddNested(nestedCtx string, nested InvalidParamsError) { - for _, err := range nested.errs { - err.SetContext(e.Context) - err.AddNestedContext(nestedCtx) - e.errs = append(e.errs, err) - } -} - -// Len returns the number of invalid parameter errors -func (e *InvalidParamsError) Len() int { - return len(e.errs) -} - -// Error returns the string formatted form of the invalid parameters. -func (e InvalidParamsError) Error() string { - w := &bytes.Buffer{} - fmt.Fprintf(w, "%d validation error(s) found.\n", len(e.errs)) - - for _, err := range e.errs { - fmt.Fprintf(w, "- %s\n", err.Error()) - } - - return w.String() -} - -// Errs returns a slice of the invalid parameters -func (e InvalidParamsError) Errs() []error { - errs := make([]error, len(e.errs)) - for i := 0; i < len(errs); i++ { - errs[i] = e.errs[i] - } - - return errs -} - -// An InvalidParamError represents an invalid parameter error type. -type InvalidParamError interface { - error - - // Field name the error occurred on. - Field() string - - // SetContext updates the context of the error. - SetContext(string) - - // AddNestedContext updates the error's context to include a nested level. - AddNestedContext(string) -} - -type invalidParamError struct { - context string - nestedContext string - field string - reason string -} - -// Error returns the string version of the invalid parameter error. -func (e invalidParamError) Error() string { - return fmt.Sprintf("%s, %s.", e.reason, e.Field()) -} - -// Field Returns the field and context the error occurred. -func (e invalidParamError) Field() string { - sb := &strings.Builder{} - sb.WriteString(e.context) - if sb.Len() > 0 { - if len(e.nestedContext) == 0 || (len(e.nestedContext) > 0 && e.nestedContext[:1] != "[") { - sb.WriteRune('.') - } - } - if len(e.nestedContext) > 0 { - sb.WriteString(e.nestedContext) - sb.WriteRune('.') - } - sb.WriteString(e.field) - return sb.String() -} - -// SetContext updates the base context of the error. -func (e *invalidParamError) SetContext(ctx string) { - e.context = ctx -} - -// AddNestedContext prepends a context to the field's path. -func (e *invalidParamError) AddNestedContext(ctx string) { - if len(e.nestedContext) == 0 { - e.nestedContext = ctx - return - } - // Check if our nested context is an index into a slice or map - if e.nestedContext[:1] != "[" { - e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext) - return - } - e.nestedContext = ctx + e.nestedContext -} - -// An ParamRequiredError represents an required parameter error. -type ParamRequiredError struct { - invalidParamError -} - -// NewErrParamRequired creates a new required parameter error. -func NewErrParamRequired(field string) *ParamRequiredError { - return &ParamRequiredError{ - invalidParamError{ - field: field, - reason: fmt.Sprintf("missing required field"), - }, - } -} diff --git a/vendor/github.com/coder/websocket/.gitignore b/vendor/github.com/coder/websocket/.gitignore new file mode 100644 index 0000000..d1941b1 --- /dev/null +++ b/vendor/github.com/coder/websocket/.gitignore @@ -0,0 +1 @@ +PLAN.md diff --git a/vendor/github.com/coder/websocket/AGENTS.md b/vendor/github.com/coder/websocket/AGENTS.md new file mode 100644 index 0000000..711bc96 --- /dev/null +++ b/vendor/github.com/coder/websocket/AGENTS.md @@ -0,0 +1,159 @@ +# Agents + +This document helps AI agents work effectively in this codebase. It explains the philosophy, patterns, and pitfalls behind the code, so you can make good decisions on any task, not just scenarios explicitly covered. + +## Philosophy + +This is a minimal, idiomatic WebSocket library. Simplicity is a feature. + +Before adding code, articulate why it's necessary in one sentence. If you cannot justify the addition, it probably isn't needed. + +Before adding a dependency, don't. Tests requiring external packages are isolated in `internal/thirdparty`. + +## Workflow + +Every task follows phases. Do not skip phases; if you realize you missed something, return to the appropriate phase. + +**Making changes:** + +1. **Research** - Understand the problem and codebase before acting +2. **Plan** - Articulate your approach before implementing (when asked, or for complex changes) +3. **Implement** - Make changes in small, verifiable steps +4. **Verify** - Confirm correctness using external tools + +For trivial changes (typo fixes, comment updates), an abbreviated workflow is acceptable. + +## Research + +Research in sequential passes. Each pass has one focus. Don't skip ahead to code until you've completed the earlier passes. + +**Pass 1: Read the issue.** If you were given a link, read it now. Do not explore code, do not pass go. Fetch the linked issue or document first. Summarize what it asks for. If you cannot restate the problem, you are not ready to proceed. + +**Pass 2: Read linked references.** Follow every link in the issue: related issues, RFCs, external docs. Document what you learn. Code comments reference RFC 6455 (WebSocket), RFC 7692 (compression), and RFC 8441 (HTTP/2). + +**Pass 3: Trace the code.** Start from public API inward: `Accept` (server) or `Dial` (client) → `Conn` → `Reader`/`Writer`. Read tests for intent; the autobahn-testsuite (`autobahn_test.go`) validates protocol compliance. + +**Pass 4: Check both platforms.** Native Go files have `//go:build !js`. WASM lives in `ws_js.go`. Same API, different implementations. WASM wraps browser APIs and cannot control framing, compression, or masking. + +**Pass 5: Search exhaustively.** If the change affects a pattern used in multiple places, grep for all instances. Missing one creates inconsistent behavior. + +**Pass 6: Document unknowns.** List what you still don't know. Unknown unknowns become known unknowns when you ask "what am I still unsure about?" + +**After all passes:** Can you restate the problem in your own words? If not, return to Pass 1. Gaps in earlier passes will cause problems later. + +## Plan + +When asked to plan, write to `PLAN.md`. Write for someone else, not yourself; don't skip context you already know. + +**Pass 1: Document research.** Summarize what you learned in Research. Follow every reference; document findings so the implementer can verify. If the research section is empty, you haven't researched enough. + +**Pass 2: Consider approaches.** For non-trivial problems, enumerate at least two approaches. For each, note: what would change, what could go wrong, what's the tradeoff. + +**Pass 3: Detail the chosen approach.** Explain what and why, not step-by-step how. Point to specific files, functions, line numbers. Make claims verifiable. Leave room for the implementer to find a better solution. + +**Pass 4: List open questions.** What's still unclear? What assumptions are you making? What would change your approach? + +**After all passes:** Review from the implementer's perspective. Could they start work with only this document? If not, add what's missing. + +## Implement + +Implement in sequential passes. Don't write code until you've completed the verification passes. + +**Pass 1: Verify understanding.** Did you do your research? Can you state your approach in one sentence? If requirements are ambiguous, stop and ask. A wrong assumption wastes more time than a quick question. + +**Pass 2: Check scope.** Does this need to exist? Check if it already exists in the API. Is this the library's job or the user's job? The library handles protocol correctness; application concerns (reconnection, auth, routing) belong in user code. + +**Pass 3: Check invariants.** Walk through Key Invariants before writing code: + +- Reads: Will something still read from the connection? +- Pools: Will pooled objects be returned on all paths? +- Locks: Are you using context-aware `mu`, not `sync.Mutex`? +- Independence: Are you coupling reads and writes unnecessarily? + +**Pass 4: Implement.** Make the change. Every change needs a reason; if you can't articulate why it improves things, don't make it. Preserve existing comments unless you can prove they're wrong. + +**Pass 5: Verify examples.** Trace through usage examples as if writing real code. If an example wouldn't compile, the design is wrong. Check edge cases: what happens on error? On cancellation? + +**After all passes:** If feedback identifies a problem, fix that specific problem. Don't pivot to a new approach without articulating what failed and why the new approach avoids it. + +## Verify + +Verify using external signals. Self-assessment is unreliable; these tools are the ground truth. + +**Pass 1: Run tests.** `go test ./...` must pass. If tests fail, return to Research to understand why, not to Implement to "fix" it. + +**Pass 2: Run vet.** `go vet ./...` must report no issues. + +**Pass 3: Check platforms.** Code must compile on both native Go and WASM. API changes need both implementations; test that method signatures match. + +**Pass 4: Protocol compliance.** For protocol changes, run `AUTOBAHN=1 go test`. Compare wire bytes when implementations disagree; check against the RFC. + +**After all passes:** If any pass fails, fix the issue and restart from Pass 1. Don't consider a change complete until all passes succeed. + +## When Uncertain + +If confidence is low or requirements are ambiguous: + +1. State what you're uncertain about +2. Identify what information would resolve the uncertainty +3. Gather that information or ask for clarification + +Do not proceed with low-confidence assumptions. + +For complex changes, approach from multiple angles. If two approaches give different answers, that discrepancy demands resolution before proceeding. + +## Code Style + +Follow Go conventions: [Effective Go](https://go.dev/doc/effective_go), [Go Code Review Comments](https://go.dev/wiki/CodeReviewComments), and [Go Proverbs](https://go-proverbs.github.io/). Be concise, declarative, and factual. + +Never use emdash. Use commas, semicolons, or separate sentences. + +**Doc comments** start with the name and state what it does. Structure: `// [Name] [verb]s [what]. [Optional: when/why to use it].` Put useful information where users make decisions (usually the constructor, not methods). + +**Inline comments** are terse. Prefer end-of-line when short enough. + +**Explain why, not what.** The code shows what it does; comments should explain reasoning, non-obvious decisions, or edge cases. + +**Wrap comments** at ~80 characters, continuing naturally at word boundaries. + +**Naming matters.** Before proposing a name, stop and review existing names in the file. Ask: what would someone assume from this name? Does it fit with how similar things are named? A good name is accurate on its own and consistent in context. + +**Comment content:** + +- Add information beyond what the code shows (not tautologies) +- State directly: "Returns X" (not "Note that this returns X") +- Drop filler: "basically", "actually", "really" add nothing + +## Key Invariants + +**Always read from connections.** Control frames (ping, pong, close) arrive on the read path. A connection that never reads will miss them and misbehave. `CloseRead` exists for write-only patterns. + +**Pooled objects must be returned.** `flate.Writer` is ~1.2MB. Leaking them causes memory growth. Follow `get*()` / `put*()` patterns; return on all paths including errors. + +**Locks must respect context.** The `mu` type in `conn.go` unblocks when context cancels or connection closes. Using `sync.Mutex` for user-facing operations would block forever on stuck connections. + +**Reads and writes are independent.** They have separate locks (`readMu`, `writeFrameMu`) and can happen concurrently. Keep them decoupled. + +**Masking is asymmetric.** Clients mask payloads; servers don't. The mask is applied into the bufio.Writer buffer, not in-place on source bytes. + +## Commits and PRs + +Use conventional commits: `type(scope): description`. Scope is optional but include it when changes are constrained to a single file or directory. + +**Choose precise verbs:** `add` (new functionality), `fix` (broken behavior), `prevent` (undesirable state), `allow` (enable action), `handle` (edge cases), `improve` (performance/quality), `use` (change approach), `skip` (bypass), `remove` (delete), `rewrite` (substantial rework). + +**Before writing the commit message**, articulate what was wrong with the previous behavior and why this change fixes it. The commit message captures this reasoning. + +**Commit messages explain why.** State what was wrong, why it mattered, and why this solution was chosen. One to three sentences. Keep the tone neutral. + +**PR descriptions are for humans.** Explain what reviewers can't see: the why, alternatives considered, and tradeoffs made. Show evidence (logs, benchmarks, screenshots). Be explicit about what the PR doesn't do. + +**Link issues:** `Fixes #123` (PR resolves it), `Refs #123` (related), `Updates #123` (partial progress). + +## RFC References + +- RFC 6455: The WebSocket Protocol +- RFC 7692: Compression Extensions for WebSocket (permessage-deflate) +- RFC 8441: Bootstrapping WebSockets with HTTP/2 + +Section numbers in code comments refer to these RFCs. diff --git a/vendor/github.com/coder/websocket/LICENSE.txt b/vendor/github.com/coder/websocket/LICENSE.txt index 77b5bef..7e79329 100644 --- a/vendor/github.com/coder/websocket/LICENSE.txt +++ b/vendor/github.com/coder/websocket/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2023 Anmol Sethi +Copyright (c) 2025 Coder Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/vendor/github.com/coder/websocket/Makefile b/vendor/github.com/coder/websocket/Makefile new file mode 100644 index 0000000..a3e4a20 --- /dev/null +++ b/vendor/github.com/coder/websocket/Makefile @@ -0,0 +1,18 @@ +.PHONY: all +all: fmt lint test + +.PHONY: fmt +fmt: + ./ci/fmt.sh + +.PHONY: lint +lint: + ./ci/lint.sh + +.PHONY: test +test: + ./ci/test.sh + +.PHONY: bench +bench: + ./ci/bench.sh \ No newline at end of file diff --git a/vendor/github.com/coder/websocket/README.md b/vendor/github.com/coder/websocket/README.md index c74b79d..3f174d5 100644 --- a/vendor/github.com/coder/websocket/README.md +++ b/vendor/github.com/coder/websocket/README.md @@ -1,7 +1,7 @@ # websocket [![Go Reference](https://pkg.go.dev/badge/github.com/coder/websocket.svg)](https://pkg.go.dev/github.com/coder/websocket) -[![Go Coverage](https://img.shields.io/badge/coverage-91%25-success)](https://github.com/coder/websocket/coverage.html) +[![Go Coverage](https://coder.github.io/websocket/coverage.svg)](https://coder.github.io/websocket/coverage.html) websocket is a minimal and idiomatic WebSocket library for Go. @@ -36,15 +36,15 @@ go get github.com/coder/websocket See GitHub issues for minor issues but the major future enhancements are: -- [ ] Perfect examples [#217](https://github.com/nhooyr/websocket/issues/217) -- [ ] wstest.Pipe for in memory testing [#340](https://github.com/nhooyr/websocket/issues/340) -- [ ] Ping pong heartbeat helper [#267](https://github.com/nhooyr/websocket/issues/267) -- [ ] Ping pong instrumentation callbacks [#246](https://github.com/nhooyr/websocket/issues/246) -- [ ] Graceful shutdown helpers [#209](https://github.com/nhooyr/websocket/issues/209) -- [ ] Assembly for WebSocket masking [#16](https://github.com/nhooyr/websocket/issues/16) - - WIP at [#326](https://github.com/nhooyr/websocket/pull/326), about 3x faster -- [ ] HTTP/2 [#4](https://github.com/nhooyr/websocket/issues/4) -- [ ] The holy grail [#402](https://github.com/nhooyr/websocket/issues/402) +- [ ] Perfect examples [#217](https://github.com/coder/websocket/issues/217) +- [ ] wstest.Pipe for in memory testing [#340](https://github.com/coder/websocket/issues/340) +- [ ] Ping pong heartbeat helper [#267](https://github.com/coder/websocket/issues/267) +- [ ] Ping pong instrumentation callbacks [#246](https://github.com/coder/websocket/issues/246) +- [ ] Graceful shutdown helpers [#209](https://github.com/coder/websocket/issues/209) +- [ ] Assembly for WebSocket masking [#16](https://github.com/coder/websocket/issues/16) + - WIP at [#326](https://github.com/coder/websocket/pull/326), about 3x faster +- [ ] HTTP/2 [#4](https://github.com/coder/websocket/issues/4) +- [ ] The holy grail [#402](https://github.com/coder/websocket/issues/402) ## Examples @@ -63,10 +63,12 @@ http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { } defer c.CloseNow() - ctx, cancel := context.WithTimeout(r.Context(), time.Second*10) + // Set the context as needed. Use of r.Context() is not recommended + // to avoid surprising behavior (see http.Hijacker). + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() - var v interface{} + var v any err = wsjson.Read(ctx, c, &v) if err != nil { // ... @@ -107,8 +109,6 @@ Advantages of [gorilla/websocket](https://github.com/gorilla/websocket): - Mature and widely used - [Prepared writes](https://pkg.go.dev/github.com/gorilla/websocket#PreparedMessage) - Configurable [buffer sizes](https://pkg.go.dev/github.com/gorilla/websocket#hdr-Buffers) -- No extra goroutine per connection to support cancellation with context.Context. This costs github.com/coder/websocket 2 KB of memory per connection. - - Will be removed soon with [context.AfterFunc](https://github.com/golang/go/issues/57928). See [#411](https://github.com/nhooyr/websocket/issues/411) Advantages of github.com/coder/websocket: @@ -126,9 +126,9 @@ Advantages of github.com/coder/websocket: - Gorilla requires registering a pong callback before sending a Ping - Can target Wasm ([gorilla/websocket#432](https://github.com/gorilla/websocket/issues/432)) - Transparent message buffer reuse with [wsjson](https://pkg.go.dev/github.com/coder/websocket/wsjson) subpackage -- [1.75x](https://github.com/nhooyr/websocket/releases/tag/v1.7.4) faster WebSocket masking implementation in pure Go +- [1.75x](https://github.com/coder/websocket/releases/tag/v1.7.4) faster WebSocket masking implementation in pure Go - Gorilla's implementation is slower and uses [unsafe](https://golang.org/pkg/unsafe/). - Soon we'll have assembly and be 3x faster [#326](https://github.com/nhooyr/websocket/pull/326) + Soon we'll have assembly and be 3x faster [#326](https://github.com/coder/websocket/pull/326) - Full [permessage-deflate](https://tools.ietf.org/html/rfc7692) compression extension support - Gorilla only supports no context takeover mode - [CloseRead](https://pkg.go.dev/github.com/coder/websocket#Conn.CloseRead) helper for write only connections ([gorilla/websocket#492](https://github.com/gorilla/websocket/issues/492)) diff --git a/vendor/github.com/coder/websocket/accept.go b/vendor/github.com/coder/websocket/accept.go index f672a73..bcfd38e 100644 --- a/vendor/github.com/coder/websocket/accept.go +++ b/vendor/github.com/coder/websocket/accept.go @@ -1,10 +1,10 @@ //go:build !js -// +build !js package websocket import ( "bytes" + "context" "crypto/sha1" "encoding/base64" "errors" @@ -14,7 +14,7 @@ import ( "net/http" "net/textproto" "net/url" - "path/filepath" + "path" "strings" "github.com/coder/websocket/internal/errd" @@ -40,9 +40,10 @@ type AcceptOptions struct { // In such a case, example.com is the origin and chat.example.com is the request host. // One would set this field to []string{"example.com"} to authorize example.com to connect. // - // Each pattern is matched case insensitively against the request origin host - // with filepath.Match. - // See https://golang.org/pkg/path/filepath/#Match + // Each pattern is matched case insensitively with path.Match (see + // https://golang.org/pkg/path/#Match). By default, it is matched + // against the request origin host. If the pattern contains a URI + // scheme ("://"), it will be matched against "scheme://host". // // Please ensure you understand the ramifications of enabling this. // If used incorrectly your WebSocket server will be open to CSRF attacks. @@ -62,6 +63,22 @@ type AcceptOptions struct { // Defaults to 512 bytes for CompressionNoContextTakeover and 128 bytes // for CompressionContextTakeover. CompressionThreshold int + + // OnPingReceived is an optional callback invoked synchronously when a ping frame is received. + // + // The payload contains the application data of the ping frame. + // If the callback returns false, the subsequent pong frame will not be sent. + // To avoid blocking, any expensive processing should be performed asynchronously using a goroutine. + OnPingReceived func(ctx context.Context, payload []byte) bool + + // OnPongReceived is an optional callback invoked synchronously when a pong frame is received. + // + // The payload contains the application data of the pong frame. + // To avoid blocking, any expensive processing should be performed asynchronously using a goroutine. + // + // Unlike OnPingReceived, this callback does not return a value because a pong frame + // is a response to a ping and does not trigger any further frame transmission. + OnPongReceived func(ctx context.Context, payload []byte) } func (opts *AcceptOptions) cloneWithDefaults() *AcceptOptions { @@ -73,12 +90,15 @@ func (opts *AcceptOptions) cloneWithDefaults() *AcceptOptions { } // Accept accepts a WebSocket handshake from a client and upgrades the -// the connection to a WebSocket. +// connection to a WebSocket. // // Accept will not allow cross origin requests by default. // See the InsecureSkipVerify and OriginPatterns options to allow cross origin requests. // // Accept will write a response to w on all errors. +// +// Note that using the http.Request Context after Accept returns may lead to +// unexpected behavior (see http.Hijacker). func Accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (*Conn, error) { return accept(w, r, opts) } @@ -96,7 +116,7 @@ func accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (_ *Con if !opts.InsecureSkipVerify { err = authenticateOrigin(r, opts.OriginPatterns) if err != nil { - if errors.Is(err, filepath.ErrBadPattern) { + if errors.Is(err, path.ErrBadPattern) { log.Printf("websocket: %v", err) err = errors.New(http.StatusText(http.StatusForbidden)) } @@ -105,7 +125,7 @@ func accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (_ *Con } } - hj, ok := w.(http.Hijacker) + hj, ok := hijacker(w) if !ok { err = errors.New("http.ResponseWriter does not implement http.Hijacker") http.Error(w, http.StatusText(http.StatusNotImplemented), http.StatusNotImplemented) @@ -153,6 +173,8 @@ func accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (_ *Con client: false, copts: copts, flateThreshold: opts.CompressionThreshold, + onPingReceived: opts.OnPingReceived, + onPongReceived: opts.OnPongReceived, br: brw.Reader, bw: brw.Writer, @@ -219,9 +241,13 @@ func authenticateOrigin(r *http.Request, originHosts []string) error { } for _, hostPattern := range originHosts { - matched, err := match(hostPattern, u.Host) + target := u.Host + if strings.Contains(hostPattern, "://") { + target = u.Scheme + "://" + u.Host + } + matched, err := match(hostPattern, target) if err != nil { - return fmt.Errorf("failed to parse filepath pattern %q: %w", hostPattern, err) + return fmt.Errorf("failed to parse path pattern %q: %w", hostPattern, err) } if matched { return nil @@ -234,7 +260,7 @@ func authenticateOrigin(r *http.Request, originHosts []string) error { } func match(pattern, s string) (bool, error) { - return filepath.Match(strings.ToLower(pattern), strings.ToLower(s)) + return path.Match(strings.ToLower(pattern), strings.ToLower(s)) } func selectSubprotocol(r *http.Request, subprotocols []string) string { diff --git a/vendor/github.com/coder/websocket/close.go b/vendor/github.com/coder/websocket/close.go index ff2e878..fcc6806 100644 --- a/vendor/github.com/coder/websocket/close.go +++ b/vendor/github.com/coder/websocket/close.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket @@ -100,7 +99,7 @@ func CloseStatus(err error) StatusCode { func (c *Conn) Close(code StatusCode, reason string) (err error) { defer errd.Wrap(&err, "failed to close WebSocket") - if !c.casClosing() { + if c.casClosing() { err = c.waitGoroutines() if err != nil { return err @@ -133,7 +132,7 @@ func (c *Conn) Close(code StatusCode, reason string) (err error) { func (c *Conn) CloseNow() (err error) { defer errd.Wrap(&err, "failed to immediately close WebSocket") - if !c.casClosing() { + if c.casClosing() { err = c.waitGoroutines() if err != nil { return err @@ -232,12 +231,6 @@ func (c *Conn) waitGoroutines() error { t := time.NewTimer(time.Second * 15) defer t.Stop() - select { - case <-c.timeoutLoopDone: - case <-t.C: - return errors.New("failed to wait for timeoutLoop goroutine to exit") - } - c.closeReadMu.Lock() closeRead := c.closeReadCtx != nil c.closeReadMu.Unlock() @@ -329,13 +322,7 @@ func (ce CloseError) bytesErr() ([]byte, error) { } func (c *Conn) casClosing() bool { - c.closeMu.Lock() - defer c.closeMu.Unlock() - if !c.closing { - c.closing = true - return true - } - return false + return c.closing.Swap(true) } func (c *Conn) isClosed() bool { diff --git a/vendor/github.com/coder/websocket/compress.go b/vendor/github.com/coder/websocket/compress.go index 1f3adcf..41bd5bd 100644 --- a/vendor/github.com/coder/websocket/compress.go +++ b/vendor/github.com/coder/websocket/compress.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket @@ -168,8 +167,10 @@ type slidingWindow struct { buf []byte } -var swPoolMu sync.RWMutex -var swPool = map[int]*sync.Pool{} +var ( + swPoolMu sync.RWMutex + swPool = map[int]*sync.Pool{} +) func slidingWindowPool(n int) *sync.Pool { swPoolMu.RLock() diff --git a/vendor/github.com/coder/websocket/conn.go b/vendor/github.com/coder/websocket/conn.go index 8690fb3..bfc78aa 100644 --- a/vendor/github.com/coder/websocket/conn.go +++ b/vendor/github.com/coder/websocket/conn.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket @@ -52,9 +51,8 @@ type Conn struct { br *bufio.Reader bw *bufio.Writer - readTimeout chan context.Context - writeTimeout chan context.Context - timeoutLoopDone chan struct{} + readTimeoutStop atomic.Pointer[func() bool] + writeTimeoutStop atomic.Pointer[func() bool] // Read state. readMu *mu @@ -69,17 +67,25 @@ type Conn struct { writeHeaderBuf [8]byte writeHeader header + // Close handshake state. + closeStateMu sync.RWMutex + closeReceivedErr error + closeSentErr error + + // CloseRead state. closeReadMu sync.Mutex closeReadCtx context.Context closeReadDone chan struct{} + closing atomic.Bool + closeMu sync.Mutex // Protects following. closed chan struct{} - closeMu sync.Mutex - closing bool - pingCounter int32 - activePingsMu sync.Mutex - activePings map[string]chan<- struct{} + pingCounter atomic.Int64 + activePingsMu sync.Mutex + activePings map[string]chan<- struct{} + onPingReceived func(context.Context, []byte) bool + onPongReceived func(context.Context, []byte) } type connConfig struct { @@ -88,6 +94,8 @@ type connConfig struct { client bool copts *compressionOptions flateThreshold int + onPingReceived func(context.Context, []byte) bool + onPongReceived func(context.Context, []byte) br *bufio.Reader bw *bufio.Writer @@ -104,12 +112,10 @@ func newConn(cfg connConfig) *Conn { br: cfg.br, bw: cfg.bw, - readTimeout: make(chan context.Context), - writeTimeout: make(chan context.Context), - timeoutLoopDone: make(chan struct{}), - - closed: make(chan struct{}), - activePings: make(map[string]chan<- struct{}), + closed: make(chan struct{}), + activePings: make(map[string]chan<- struct{}), + onPingReceived: cfg.onPingReceived, + onPongReceived: cfg.onPongReceived, } c.readMu = newMu(c) @@ -133,8 +139,6 @@ func newConn(cfg connConfig) *Conn { c.close() }) - go c.timeoutLoop() - return c } @@ -164,27 +168,44 @@ func (c *Conn) close() error { return err } -func (c *Conn) timeoutLoop() { - defer close(c.timeoutLoopDone) +func (c *Conn) setupWriteTimeout(ctx context.Context) bool { + if ctx.Done() == nil { + return false + } - readCtx := context.Background() - writeCtx := context.Background() + stop := context.AfterFunc(ctx, func() { + c.clearWriteTimeout() + c.close() + }) + swapTimeoutStop(&c.writeTimeoutStop, &stop) + return true +} - for { - select { - case <-c.closed: - return +func (c *Conn) clearWriteTimeout() { + swapTimeoutStop(&c.writeTimeoutStop, nil) +} - case writeCtx = <-c.writeTimeout: - case readCtx = <-c.readTimeout: +func (c *Conn) setupReadTimeout(ctx context.Context) bool { + if ctx.Done() == nil { + return false + } - case <-readCtx.Done(): - c.close() - return - case <-writeCtx.Done(): - c.close() - return - } + stop := context.AfterFunc(ctx, func() { + c.clearReadTimeout() + c.close() + }) + swapTimeoutStop(&c.readTimeoutStop, &stop) + return true +} + +func (c *Conn) clearReadTimeout() { + swapTimeoutStop(&c.readTimeoutStop, nil) +} + +func swapTimeoutStop(p *atomic.Pointer[func() bool], newStop *func() bool) { + oldStop := p.Swap(newStop) + if oldStop != nil { + (*oldStop)() } } @@ -200,9 +221,9 @@ func (c *Conn) flate() bool { // // TCP Keepalives should suffice for most use cases. func (c *Conn) Ping(ctx context.Context) error { - p := atomic.AddInt32(&c.pingCounter, 1) + p := c.pingCounter.Add(1) - err := c.ping(ctx, strconv.Itoa(int(p))) + err := c.ping(ctx, strconv.FormatInt(p, 10)) if err != nil { return fmt.Errorf("failed to ping: %w", err) } diff --git a/vendor/github.com/coder/websocket/dial.go b/vendor/github.com/coder/websocket/dial.go index ad61a35..f5e4544 100644 --- a/vendor/github.com/coder/websocket/dial.go +++ b/vendor/github.com/coder/websocket/dial.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket @@ -48,6 +47,22 @@ type DialOptions struct { // Defaults to 512 bytes for CompressionNoContextTakeover and 128 bytes // for CompressionContextTakeover. CompressionThreshold int + + // OnPingReceived is an optional callback invoked synchronously when a ping frame is received. + // + // The payload contains the application data of the ping frame. + // If the callback returns false, the subsequent pong frame will not be sent. + // To avoid blocking, any expensive processing should be performed asynchronously using a goroutine. + OnPingReceived func(ctx context.Context, payload []byte) bool + + // OnPongReceived is an optional callback invoked synchronously when a pong frame is received. + // + // The payload contains the application data of the pong frame. + // To avoid blocking, any expensive processing should be performed asynchronously using a goroutine. + // + // Unlike OnPingReceived, this callback does not return a value because a pong frame + // is a response to a ping and does not trigger any further frame transmission. + OnPongReceived func(ctx context.Context, payload []byte) } func (opts *DialOptions) cloneWithDefaults(ctx context.Context) (context.Context, context.CancelFunc, *DialOptions) { @@ -163,6 +178,8 @@ func dial(ctx context.Context, urls string, opts *DialOptions, rand io.Reader) ( client: true, copts: copts, flateThreshold: opts.CompressionThreshold, + onPingReceived: opts.OnPingReceived, + onPongReceived: opts.OnPongReceived, br: getBufioReader(rwc), bw: getBufioWriter(rwc), }), resp, nil diff --git a/vendor/github.com/coder/websocket/doc.go b/vendor/github.com/coder/websocket/doc.go index 03edf12..0c7f831 100644 --- a/vendor/github.com/coder/websocket/doc.go +++ b/vendor/github.com/coder/websocket/doc.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js // Package websocket implements the RFC 6455 WebSocket protocol. // diff --git a/vendor/github.com/coder/websocket/errors.go b/vendor/github.com/coder/websocket/errors.go new file mode 100644 index 0000000..bf4fc2b --- /dev/null +++ b/vendor/github.com/coder/websocket/errors.go @@ -0,0 +1,8 @@ +package websocket + +import ( + "errors" +) + +// ErrMessageTooBig is returned when a message exceeds the read limit. +var ErrMessageTooBig = errors.New("websocket: message too big") diff --git a/vendor/github.com/coder/websocket/hijack.go b/vendor/github.com/coder/websocket/hijack.go new file mode 100644 index 0000000..9cce45c --- /dev/null +++ b/vendor/github.com/coder/websocket/hijack.go @@ -0,0 +1,33 @@ +//go:build !js + +package websocket + +import ( + "net/http" +) + +type rwUnwrapper interface { + Unwrap() http.ResponseWriter +} + +// hijacker returns the Hijacker interface of the http.ResponseWriter. +// It follows the Unwrap method of the http.ResponseWriter if available, +// matching the behavior of http.ResponseController. If the Hijacker +// interface is not found, it returns false. +// +// Since the http.ResponseController is not available in Go 1.19, and +// does not support checking the presence of the Hijacker interface, +// this function is used to provide a consistent way to check for the +// Hijacker interface across Go versions. +func hijacker(rw http.ResponseWriter) (http.Hijacker, bool) { + for { + switch t := rw.(type) { + case http.Hijacker: + return t, true + case rwUnwrapper: + rw = t.Unwrap() + default: + return nil, false + } + } +} diff --git a/vendor/github.com/coder/websocket/internal/bpool/bpool.go b/vendor/github.com/coder/websocket/internal/bpool/bpool.go index aa826fb..12cf577 100644 --- a/vendor/github.com/coder/websocket/internal/bpool/bpool.go +++ b/vendor/github.com/coder/websocket/internal/bpool/bpool.go @@ -5,15 +5,16 @@ import ( "sync" ) -var bpool sync.Pool +var bpool = sync.Pool{ + New: func() any { + return &bytes.Buffer{} + }, +} // Get returns a buffer from the pool or creates a new one if // the pool is empty. func Get() *bytes.Buffer { b := bpool.Get() - if b == nil { - return &bytes.Buffer{} - } return b.(*bytes.Buffer) } diff --git a/vendor/github.com/coder/websocket/internal/errd/wrap.go b/vendor/github.com/coder/websocket/internal/errd/wrap.go index 6e77913..c80d0a6 100644 --- a/vendor/github.com/coder/websocket/internal/errd/wrap.go +++ b/vendor/github.com/coder/websocket/internal/errd/wrap.go @@ -7,7 +7,7 @@ import ( // Wrap wraps err with fmt.Errorf if err is non nil. // Intended for use with defer and a named error return. // Inspired by https://github.com/golang/go/issues/32676. -func Wrap(err *error, f string, v ...interface{}) { +func Wrap(err *error, f string, v ...any) { if *err != nil { *err = fmt.Errorf(f+": %w", append(v, *err)...) } diff --git a/vendor/github.com/coder/websocket/internal/wsjs/wsjs_js.go b/vendor/github.com/coder/websocket/internal/wsjs/wsjs_js.go index 11eb59c..45ecf49 100644 --- a/vendor/github.com/coder/websocket/internal/wsjs/wsjs_js.go +++ b/vendor/github.com/coder/websocket/internal/wsjs/wsjs_js.go @@ -33,7 +33,7 @@ func New(url string, protocols []string) (c WebSocket, err error) { c = WebSocket{} }) - jsProtocols := make([]interface{}, len(protocols)) + jsProtocols := make([]any, len(protocols)) for i, p := range protocols { jsProtocols[i] = p } @@ -57,7 +57,7 @@ func (c WebSocket) setBinaryType(typ string) { } func (c WebSocket) addEventListener(eventType string, fn func(e js.Value)) func() { - f := js.FuncOf(func(this js.Value, args []js.Value) interface{} { + f := js.FuncOf(func(this js.Value, args []js.Value) any { fn(args[0]) return nil }) @@ -97,7 +97,7 @@ func (c WebSocket) OnError(fn func(e js.Value)) (remove func()) { // MessageEvent is the type passed to a message handler. type MessageEvent struct { // string or []byte. - Data interface{} + Data any // There are more fields to the interface but we don't use them. // See https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent @@ -106,7 +106,7 @@ type MessageEvent struct { // OnMessage registers a function to be called when the WebSocket receives a message. func (c WebSocket) OnMessage(fn func(m MessageEvent)) (remove func()) { return c.addEventListener("message", func(e js.Value) { - var data interface{} + var data any arrayBuffer := e.Get("data") if arrayBuffer.Type() == js.TypeString { diff --git a/vendor/github.com/coder/websocket/internal/xsync/go.go b/vendor/github.com/coder/websocket/internal/xsync/go.go deleted file mode 100644 index 5229b12..0000000 --- a/vendor/github.com/coder/websocket/internal/xsync/go.go +++ /dev/null @@ -1,26 +0,0 @@ -package xsync - -import ( - "fmt" - "runtime/debug" -) - -// Go allows running a function in another goroutine -// and waiting for its error. -func Go(fn func() error) <-chan error { - errs := make(chan error, 1) - go func() { - defer func() { - r := recover() - if r != nil { - select { - case errs <- fmt.Errorf("panic in go fn: %v, %s", r, debug.Stack()): - default: - } - } - }() - errs <- fn() - }() - - return errs -} diff --git a/vendor/github.com/coder/websocket/internal/xsync/int64.go b/vendor/github.com/coder/websocket/internal/xsync/int64.go deleted file mode 100644 index a0c4020..0000000 --- a/vendor/github.com/coder/websocket/internal/xsync/int64.go +++ /dev/null @@ -1,23 +0,0 @@ -package xsync - -import ( - "sync/atomic" -) - -// Int64 represents an atomic int64. -type Int64 struct { - // We do not use atomic.Load/StoreInt64 since it does not - // work on 32 bit computers but we need 64 bit integers. - i atomic.Value -} - -// Load loads the int64. -func (v *Int64) Load() int64 { - i, _ := v.i.Load().(int64) - return i -} - -// Store stores the int64. -func (v *Int64) Store(i int64) { - v.i.Store(i) -} diff --git a/vendor/github.com/coder/websocket/make.sh b/vendor/github.com/coder/websocket/make.sh deleted file mode 100644 index 170d00a..0000000 --- a/vendor/github.com/coder/websocket/make.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -set -eu -cd -- "$(dirname "$0")" - -echo "=== fmt.sh" -./ci/fmt.sh -echo "=== lint.sh" -./ci/lint.sh -echo "=== test.sh" -./ci/test.sh "$@" -echo "=== bench.sh" -./ci/bench.sh diff --git a/vendor/github.com/coder/websocket/netconn.go b/vendor/github.com/coder/websocket/netconn.go index 86f7dad..1f73b04 100644 --- a/vendor/github.com/coder/websocket/netconn.go +++ b/vendor/github.com/coder/websocket/netconn.go @@ -68,7 +68,7 @@ func NetConn(ctx context.Context, c *Conn, msgType MessageType) net.Conn { defer nc.writeMu.unlock() // Prevents future writes from writing until the deadline is reset. - atomic.StoreInt64(&nc.writeExpired, 1) + nc.writeExpired.Store(1) }) if !nc.writeTimer.Stop() { <-nc.writeTimer.C @@ -84,7 +84,7 @@ func NetConn(ctx context.Context, c *Conn, msgType MessageType) net.Conn { defer nc.readMu.unlock() // Prevents future reads from reading until the deadline is reset. - atomic.StoreInt64(&nc.readExpired, 1) + nc.readExpired.Store(1) }) if !nc.readTimer.Stop() { <-nc.readTimer.C @@ -94,25 +94,22 @@ func NetConn(ctx context.Context, c *Conn, msgType MessageType) net.Conn { } type netConn struct { - // These must be first to be aligned on 32 bit platforms. - // https://github.com/nhooyr/websocket/pull/438 - readExpired int64 - writeExpired int64 - c *Conn msgType MessageType - writeTimer *time.Timer - writeMu *mu - writeCtx context.Context - writeCancel context.CancelFunc + writeTimer *time.Timer + writeMu *mu + writeExpired atomic.Int64 + writeCtx context.Context + writeCancel context.CancelFunc - readTimer *time.Timer - readMu *mu - readCtx context.Context - readCancel context.CancelFunc - readEOFed bool - reader io.Reader + readTimer *time.Timer + readMu *mu + readExpired atomic.Int64 + readCtx context.Context + readCancel context.CancelFunc + readEOFed bool + reader io.Reader } var _ net.Conn = &netConn{} @@ -129,7 +126,7 @@ func (nc *netConn) Write(p []byte) (int, error) { nc.writeMu.forceLock() defer nc.writeMu.unlock() - if atomic.LoadInt64(&nc.writeExpired) == 1 { + if nc.writeExpired.Load() == 1 { return 0, fmt.Errorf("failed to write: %w", context.DeadlineExceeded) } @@ -157,7 +154,7 @@ func (nc *netConn) Read(p []byte) (int, error) { } func (nc *netConn) read(p []byte) (int, error) { - if atomic.LoadInt64(&nc.readExpired) == 1 { + if nc.readExpired.Load() == 1 { return 0, fmt.Errorf("failed to read: %w", context.DeadlineExceeded) } @@ -191,8 +188,7 @@ func (nc *netConn) read(p []byte) (int, error) { return n, err } -type websocketAddr struct { -} +type websocketAddr struct{} func (a websocketAddr) Network() string { return "websocket" @@ -209,7 +205,7 @@ func (nc *netConn) SetDeadline(t time.Time) error { } func (nc *netConn) SetWriteDeadline(t time.Time) error { - atomic.StoreInt64(&nc.writeExpired, 0) + nc.writeExpired.Store(0) if t.IsZero() { nc.writeTimer.Stop() } else { @@ -223,7 +219,7 @@ func (nc *netConn) SetWriteDeadline(t time.Time) error { } func (nc *netConn) SetReadDeadline(t time.Time) error { - atomic.StoreInt64(&nc.readExpired, 0) + nc.readExpired.Store(0) if t.IsZero() { nc.readTimer.Stop() } else { diff --git a/vendor/github.com/coder/websocket/netconn_notjs.go b/vendor/github.com/coder/websocket/netconn_notjs.go index f3eb0d6..cab7634 100644 --- a/vendor/github.com/coder/websocket/netconn_notjs.go +++ b/vendor/github.com/coder/websocket/netconn_notjs.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket diff --git a/vendor/github.com/coder/websocket/read.go b/vendor/github.com/coder/websocket/read.go index 1b9404b..c19f41d 100644 --- a/vendor/github.com/coder/websocket/read.go +++ b/vendor/github.com/coder/websocket/read.go @@ -1,5 +1,4 @@ //go:build !js -// +build !js package websocket @@ -11,11 +10,11 @@ import ( "io" "net" "strings" + "sync/atomic" "time" "github.com/coder/websocket/internal/errd" "github.com/coder/websocket/internal/util" - "github.com/coder/websocket/internal/xsync" ) // Reader reads from the connection until there is a WebSocket @@ -91,7 +90,8 @@ func (c *Conn) CloseRead(ctx context.Context) context.Context { // // By default, the connection has a message read limit of 32768 bytes. // -// When the limit is hit, the connection will be closed with StatusMessageTooBig. +// When the limit is hit, reads return an error wrapping ErrMessageTooBig and +// the connection is closed with StatusMessageTooBig. // // Set to -1 to disable. func (c *Conn) SetReadLimit(n int64) { @@ -217,60 +217,74 @@ func (c *Conn) readLoop(ctx context.Context) (header, error) { } } -func (c *Conn) readFrameHeader(ctx context.Context) (header, error) { +// prepareRead sets the read timeout and checks whether the connection is closed. +func (c *Conn) prepareRead(ctx context.Context) (bool, error) { select { case <-c.closed: - return header{}, net.ErrClosed - case c.readTimeout <- ctx: + return false, net.ErrClosed + default: } + timeoutSet := c.setupReadTimeout(ctx) + + c.closeStateMu.Lock() + closeReceivedErr := c.closeReceivedErr + c.closeStateMu.Unlock() + if closeReceivedErr != nil { + if timeoutSet { + c.clearReadTimeout() + } + return false, closeReceivedErr + } + + return timeoutSet, nil +} + +// finishRead clears the read timeout and reports whether the connection or +// operation context ended while the read was in progress. +func (c *Conn) finishRead(ctx context.Context, err *error, timeoutSet bool) { + if timeoutSet { + c.clearReadTimeout() + } + select { + case <-c.closed: + if *err != nil { + *err = net.ErrClosed + } + default: + } + if *err != nil && ctx.Err() != nil { + *err = ctx.Err() + } +} + +func (c *Conn) readFrameHeader(ctx context.Context) (_ header, err error) { + timeoutSet, err := c.prepareRead(ctx) + if err != nil { + return header{}, err + } + defer c.finishRead(ctx, &err, timeoutSet) h, err := readFrameHeader(c.br, c.readHeaderBuf[:]) if err != nil { - select { - case <-c.closed: - return header{}, net.ErrClosed - case <-ctx.Done(): - return header{}, ctx.Err() - default: - return header{}, err - } - } - - select { - case <-c.closed: - return header{}, net.ErrClosed - case c.readTimeout <- context.Background(): + return header{}, err } return h, nil } -func (c *Conn) readFramePayload(ctx context.Context, p []byte) (int, error) { - select { - case <-c.closed: - return 0, net.ErrClosed - case c.readTimeout <- ctx: +func (c *Conn) readFramePayload(ctx context.Context, p []byte) (_ int, err error) { + timeoutSet, err := c.prepareRead(ctx) + if err != nil { + return 0, err } + defer c.finishRead(ctx, &err, timeoutSet) n, err := io.ReadFull(c.br, p) if err != nil { - select { - case <-c.closed: - return n, net.ErrClosed - case <-ctx.Done(): - return n, ctx.Err() - default: - return n, fmt.Errorf("failed to read frame payload: %w", err) - } + return n, fmt.Errorf("failed to read frame payload: %w", err) } - select { - case <-c.closed: - return n, net.ErrClosed - case c.readTimeout <- context.Background(): - } - - return n, err + return n, nil } func (c *Conn) handleControl(ctx context.Context, h header) (err error) { @@ -301,8 +315,16 @@ func (c *Conn) handleControl(ctx context.Context, h header) (err error) { switch h.opcode { case opPing: + if c.onPingReceived != nil { + if !c.onPingReceived(ctx, b) { + return nil + } + } return c.writeControl(ctx, opPong, b) case opPong: + if c.onPongReceived != nil { + c.onPongReceived(ctx, b) + } c.activePingsMu.Lock() pong, ok := c.activePings[string(b)] c.activePingsMu.Unlock() @@ -325,9 +347,22 @@ func (c *Conn) handleControl(ctx context.Context, h header) (err error) { } err = fmt.Errorf("received close frame: %w", ce) - c.writeClose(ce.Code, ce.Reason) - c.readMu.unlock() - c.close() + c.closeStateMu.Lock() + c.closeReceivedErr = err + closeSent := c.closeSentErr != nil + c.closeStateMu.Unlock() + + // Only unlock readMu if this connection is being closed becaue + // c.close will try to acquire the readMu lock. We unlock for + // writeClose as well because it may also call c.close. + if !closeSent { + c.readMu.unlock() + _ = c.writeClose(ce.Code, ce.Reason) + } + if !c.casClosing() { + c.readMu.unlock() + _ = c.close() + } return err } @@ -465,7 +500,7 @@ func (mr *msgReader) read(p []byte) (int, error) { type limitReader struct { c *Conn r io.Reader - limit xsync.Int64 + limit atomic.Int64 n int64 } @@ -489,9 +524,9 @@ func (lr *limitReader) Read(p []byte) (int, error) { } if lr.n == 0 { - err := fmt.Errorf("read limited at %v bytes", lr.limit.Load()) - lr.c.writeError(StatusMessageTooBig, err) - return 0, err + reason := fmt.Errorf("read limited at %d bytes", lr.limit.Load()) + lr.c.writeError(StatusMessageTooBig, reason) + return 0, fmt.Errorf("%w: %v", ErrMessageTooBig, reason) } if int64(len(p)) > lr.n { diff --git a/vendor/github.com/coder/websocket/write.go b/vendor/github.com/coder/websocket/write.go index e294a68..81bab4f 100644 --- a/vendor/github.com/coder/websocket/write.go +++ b/vendor/github.com/coder/websocket/write.go @@ -1,10 +1,10 @@ //go:build !js -// +build !js package websocket import ( "bufio" + "compress/flate" "context" "crypto/rand" "encoding/binary" @@ -14,8 +14,7 @@ import ( "net" "time" - "compress/flate" - + "github.com/coder/websocket/internal/bpool" "github.com/coder/websocket/internal/errd" "github.com/coder/websocket/internal/util" ) @@ -102,23 +101,17 @@ func (c *Conn) writer(ctx context.Context, typ MessageType) (io.WriteCloser, err } func (c *Conn) write(ctx context.Context, typ MessageType, p []byte) (int, error) { - mw, err := c.writer(ctx, typ) + err := c.msgWriter.reset(ctx, typ) if err != nil { return 0, err } + defer c.msgWriter.mu.unlock() - if !c.flate() { - defer c.msgWriter.mu.unlock() + if !c.flate() || len(p) < c.flateThreshold { return c.writeFrame(ctx, true, false, c.msgWriter.opcode, p) } - n, err := mw.Write(p) - if err != nil { - return n, err - } - - err = mw.Close() - return n, err + return c.msgWriter.writeCompressedFrame(ctx, p) } func (mw *msgWriter) reset(ctx context.Context, typ MessageType) error { @@ -144,6 +137,56 @@ func (mw *msgWriter) putFlateWriter() { } } +// writeCompressedFrame compresses and writes p as a single frame. +func (mw *msgWriter) writeCompressedFrame(ctx context.Context, p []byte) (int, error) { + err := mw.writeMu.lock(mw.ctx) + if err != nil { + return 0, fmt.Errorf("failed to write: %w", err) + } + defer mw.writeMu.unlock() + + if mw.closed { + return 0, errors.New("cannot use closed writer") + } + + mw.ensureFlate() + + buf := bpool.Get() + defer bpool.Put(buf) + + // Buffer compressed output so we can write as + // a single frame instead of chunked frames. + origWriter := mw.trimWriter.w + mw.trimWriter.w = buf + defer func() { + mw.trimWriter.w = origWriter + }() + + _, err = mw.flateWriter.Write(p) + if err != nil { + return 0, fmt.Errorf("failed to compress: %w", err) + } + + err = mw.flateWriter.Flush() + if err != nil { + return 0, fmt.Errorf("failed to flush compression: %w", err) + } + + mw.trimWriter.reset() + + if !mw.flateContextTakeover() { + mw.putFlateWriter() + } + + mw.closed = true + + _, err = mw.c.writeFrame(ctx, true, true, mw.opcode, buf.Bytes()) + if err != nil { + return 0, err + } + return len(p), nil +} + // Write writes the given bytes to the WebSocket connection. func (mw *msgWriter) Write(p []byte) (_ int, err error) { err = mw.writeMu.lock(mw.ctx) @@ -249,25 +292,36 @@ func (c *Conn) writeFrame(ctx context.Context, fin bool, flate bool, opcode opco } defer c.writeFrameMu.unlock() - select { - case <-c.closed: - return 0, net.ErrClosed - case c.writeTimeout <- ctx: - } - defer func() { + if c.isClosed() && opcode == opClose { + err = nil + } if err != nil { - select { - case <-c.closed: - err = net.ErrClosed - case <-ctx.Done(): + if ctx.Err() != nil { err = ctx.Err() - default: + } else if c.isClosed() { + err = net.ErrClosed } err = fmt.Errorf("failed to write frame: %w", err) } }() + c.closeStateMu.Lock() + closeSentErr := c.closeSentErr + c.closeStateMu.Unlock() + if closeSentErr != nil { + return 0, net.ErrClosed + } + + select { + case <-c.closed: + return 0, net.ErrClosed + default: + } + if c.setupWriteTimeout(ctx) { + defer c.clearWriteTimeout() + } + c.writeHeader.fin = fin c.writeHeader.opcode = opcode c.writeHeader.payloadLength = int64(len(p)) @@ -303,13 +357,16 @@ func (c *Conn) writeFrame(ctx context.Context, fin bool, flate bool, opcode opco } } - select { - case <-c.closed: - if opcode == opClose { - return n, nil + if opcode == opClose { + c.closeStateMu.Lock() + c.closeSentErr = fmt.Errorf("sent close frame: %w", net.ErrClosed) + closeReceived := c.closeReceivedErr != nil + c.closeStateMu.Unlock() + + if closeReceived && !c.casClosing() { + c.writeFrameMu.unlock() + _ = c.close() } - return n, net.ErrClosed - case c.writeTimeout <- context.Background(): } return n, nil @@ -335,10 +392,7 @@ func (c *Conn) writeFramePayload(p []byte) (n int, err error) { // Start of next write in the buffer. i := c.bw.Buffered() - j := len(p) - if j > c.bw.Available() { - j = c.bw.Available() - } + j := min(len(p), c.bw.Available()) _, err := c.bw.Write(p[:j]) if err != nil { diff --git a/vendor/github.com/coder/websocket/ws_js.go b/vendor/github.com/coder/websocket/ws_js.go index a8de0c6..026b75f 100644 --- a/vendor/github.com/coder/websocket/ws_js.go +++ b/vendor/github.com/coder/websocket/ws_js.go @@ -12,11 +12,11 @@ import ( "runtime" "strings" "sync" + "sync/atomic" "syscall/js" "github.com/coder/websocket/internal/bpool" "github.com/coder/websocket/internal/wsjs" - "github.com/coder/websocket/internal/xsync" ) // opcode represents a WebSocket opcode. @@ -45,7 +45,7 @@ type Conn struct { ws wsjs.WebSocket // read limit for a message in bytes. - msgReadLimit xsync.Int64 + msgReadLimit atomic.Int64 closeReadMu sync.Mutex closeReadCtx context.Context @@ -144,9 +144,9 @@ func (c *Conn) Read(ctx context.Context) (MessageType, []byte, error) { } readLimit := c.msgReadLimit.Load() if readLimit >= 0 && int64(len(p)) > readLimit { - err := fmt.Errorf("read limited at %v bytes", c.msgReadLimit.Load()) - c.Close(StatusMessageTooBig, err.Error()) - return 0, nil, err + reason := fmt.Errorf("read limited at %d bytes", c.msgReadLimit.Load()) + c.Close(StatusMessageTooBig, reason.Error()) + return 0, nil, fmt.Errorf("%w: %v", ErrMessageTooBig, reason) } return typ, p, nil } @@ -196,7 +196,7 @@ func (c *Conn) Ping(ctx context.Context) error { // Write writes a message of the given type to the connection. // Always non blocking. func (c *Conn) Write(ctx context.Context, typ MessageType, p []byte) error { - err := c.write(ctx, typ, p) + err := c.write(typ, p) if err != nil { // Have to ensure the WebSocket is closed after a write error // to match the Go API. It can only error if the message type @@ -210,7 +210,7 @@ func (c *Conn) Write(ctx context.Context, typ MessageType, p []byte) error { return nil } -func (c *Conn) write(ctx context.Context, typ MessageType, p []byte) error { +func (c *Conn) write(typ MessageType, p []byte) error { if c.isClosed() { return net.ErrClosed } diff --git a/vendor/github.com/creachadair/msync/trigger/trigger.go b/vendor/github.com/creachadair/msync/trigger/trigger.go index 1422407..1cd4047 100644 --- a/vendor/github.com/creachadair/msync/trigger/trigger.go +++ b/vendor/github.com/creachadair/msync/trigger/trigger.go @@ -1,4 +1,4 @@ -// Package trigger implements channel-based condition variable. +// Package trigger implements a channel-based condition variable. package trigger import "sync" diff --git a/vendor/github.com/dblohm7/wingoes/com/automation/types.go b/vendor/github.com/dblohm7/wingoes/com/automation/types.go index 5c94fa7..82b77bc 100644 --- a/vendor/github.com/dblohm7/wingoes/com/automation/types.go +++ b/vendor/github.com/dblohm7/wingoes/com/automation/types.go @@ -50,8 +50,8 @@ func (bs *BSTR) String() string { return windows.UTF16ToString(bs.toUTF16()) } -// toUTF16 is unsafe for general use because it returns a pointer that is -// not managed by the Go GC. +// toUTF16 is unsafe for general use because it returns a slice referencing a +// pointer that is not managed by the Go GC. func (bs *BSTR) toUTF16() []uint16 { return unsafe.Slice(bs.toUTF16Ptr(), bs.Len()) } @@ -67,7 +67,7 @@ func (bs *BSTR) toUTF16Ptr() *uint16 { return (*uint16)(unsafe.Pointer(*bs)) } -// ToUTF16 returns the contents of bs as C-style string pointer to UTF-16 code units. +// ToUTF16Ptr returns the contents of bs as C-style string pointer to UTF-16 code units. func (bs *BSTR) ToUTF16Ptr() *uint16 { return unsafe.SliceData(bs.ToUTF16()) } diff --git a/vendor/github.com/dblohm7/wingoes/com/automation/zsyscall_windows.go b/vendor/github.com/dblohm7/wingoes/com/automation/zsyscall_windows.go index 266f58d..73d7ddf 100644 --- a/vendor/github.com/dblohm7/wingoes/com/automation/zsyscall_windows.go +++ b/vendor/github.com/dblohm7/wingoes/com/automation/zsyscall_windows.go @@ -47,24 +47,24 @@ var ( ) func sysAllocString(str *uint16) (ret BSTR) { - r0, _, _ := syscall.Syscall(procSysAllocString.Addr(), 1, uintptr(unsafe.Pointer(str)), 0, 0) + r0, _, _ := syscall.SyscallN(procSysAllocString.Addr(), uintptr(unsafe.Pointer(str))) ret = BSTR(r0) return } func sysAllocStringLen(str *uint16, strLen uint32) (ret BSTR) { - r0, _, _ := syscall.Syscall(procSysAllocStringLen.Addr(), 2, uintptr(unsafe.Pointer(str)), uintptr(strLen), 0) + r0, _, _ := syscall.SyscallN(procSysAllocStringLen.Addr(), uintptr(unsafe.Pointer(str)), uintptr(strLen)) ret = BSTR(r0) return } func sysFreeString(bstr BSTR) { - syscall.Syscall(procSysFreeString.Addr(), 1, uintptr(bstr), 0, 0) + syscall.SyscallN(procSysFreeString.Addr(), uintptr(bstr)) return } func sysStringLen(bstr BSTR) (ret uint32) { - r0, _, _ := syscall.Syscall(procSysStringLen.Addr(), 1, uintptr(bstr), 0, 0) + r0, _, _ := syscall.SyscallN(procSysStringLen.Addr(), uintptr(bstr)) ret = uint32(r0) return } diff --git a/vendor/github.com/dblohm7/wingoes/com/mksyscall.go b/vendor/github.com/dblohm7/wingoes/com/mksyscall.go index f26be96..351e54e 100644 --- a/vendor/github.com/dblohm7/wingoes/com/mksyscall.go +++ b/vendor/github.com/dblohm7/wingoes/com/mksyscall.go @@ -20,6 +20,5 @@ package com // Technically this proc is __cdecl, but since it has 0 args this doesn't matter //sys setOaNoCache() = oleaut32.SetOaNoCache -// For the following two functions we use IUnknownABI instead of IStreamABI because it makes the callsites cleaner. +// The following function uses IUnknownABI instead of IStreamABI because it makes the callsite cleaner. //sys shCreateMemStream(pInit *byte, cbInit uint32) (stream *IUnknownABI) = shlwapi.SHCreateMemStream -//sys createStreamOnHGlobal(hglobal internal.HGLOBAL, deleteOnRelease bool, stream **IUnknownABI) (hr wingoes.HRESULT) = ole32.CreateStreamOnHGlobal diff --git a/vendor/github.com/dblohm7/wingoes/com/stream.go b/vendor/github.com/dblohm7/wingoes/com/stream.go index b0f7b9d..80b1eb2 100644 --- a/vendor/github.com/dblohm7/wingoes/com/stream.go +++ b/vendor/github.com/dblohm7/wingoes/com/stream.go @@ -13,7 +13,6 @@ import ( "unsafe" "github.com/dblohm7/wingoes" - "github.com/dblohm7/wingoes/internal" "golang.org/x/sys/windows" ) @@ -179,103 +178,6 @@ func (o SequentialStream) Write(b []byte) (int, error) { return p.Write(b) } -func (abi *IStreamABI) Seek(offset int64, whence int) (n int64, _ error) { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[5] - - if runtime.GOARCH == "386" { - words := (*[2]uintptr)(unsafe.Pointer(&offset)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - words[0], - words[1], - uintptr(uint32(whence)), - uintptr(unsafe.Pointer(&n)), - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(offset), - uintptr(uint32(whence)), - uintptr(unsafe.Pointer(&n)), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return 0, e - } - - return n, nil -} - -func (abi *IStreamABI) SetSize(newSize uint64) error { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[6] - - if runtime.GOARCH == "386" { - words := (*[2]uintptr)(unsafe.Pointer(&newSize)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - words[0], - words[1], - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(newSize), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return e - } - - return nil -} - -func (abi *IStreamABI) CopyTo(dest *IStreamABI, numBytesToCopy uint64) (bytesRead, bytesWritten uint64, _ error) { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[7] - - if runtime.GOARCH == "386" { - words := (*[2]uintptr)(unsafe.Pointer(&numBytesToCopy)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(unsafe.Pointer(dest)), - words[0], - words[1], - uintptr(unsafe.Pointer(&bytesRead)), - uintptr(unsafe.Pointer(&bytesWritten)), - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(unsafe.Pointer(dest)), - uintptr(numBytesToCopy), - uintptr(unsafe.Pointer(&bytesRead)), - uintptr(unsafe.Pointer(&bytesWritten)), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return bytesRead, bytesWritten, e - } - - return bytesRead, bytesWritten, nil -} - func (abi *IStreamABI) Commit(flags STGC) error { method := unsafe.Slice(abi.Vtbl, 14)[8] @@ -306,76 +208,6 @@ func (abi *IStreamABI) Revert() error { return nil } -func (abi *IStreamABI) LockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[10] - - if runtime.GOARCH == "386" { - oWords := (*[2]uintptr)(unsafe.Pointer(&offset)) - nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - oWords[0], - oWords[1], - nWords[0], - nWords[1], - uintptr(lockType), - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(offset), - uintptr(numBytes), - uintptr(lockType), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return e - } - - return nil -} - -func (abi *IStreamABI) UnlockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { - var hr wingoes.HRESULT - method := unsafe.Slice(abi.Vtbl, 14)[11] - - if runtime.GOARCH == "386" { - oWords := (*[2]uintptr)(unsafe.Pointer(&offset)) - nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes)) - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - oWords[0], - oWords[1], - nWords[0], - nWords[1], - uintptr(lockType), - ) - hr = wingoes.HRESULT(rc) - } else { - rc, _, _ := syscall.SyscallN( - method, - uintptr(unsafe.Pointer(abi)), - uintptr(offset), - uintptr(numBytes), - uintptr(lockType), - ) - hr = wingoes.HRESULT(rc) - } - - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return e - } - - return nil -} - func (abi *IStreamABI) Stat(flags STATFLAG) (*STATSTG, error) { result := new(STATSTG) method := unsafe.Slice(abi.Vtbl, 14)[12] @@ -493,19 +325,10 @@ const hrE_OUTOFMEMORY = wingoes.HRESULT(-((0x8007000E ^ 0xFFFFFFFF) + 1)) // copy of initialBytes. Its seek pointer is guaranteed to reference the // beginning of the stream. func NewMemoryStream(initialBytes []byte) (result Stream, _ error) { - return newMemoryStreamInternal(initialBytes, false) -} - -func newMemoryStreamInternal(initialBytes []byte, forceLegacy bool) (result Stream, _ error) { if len(initialBytes) > maxStreamRWLen { return result, wingoes.ErrorFromHRESULT(hrE_OUTOFMEMORY) } - // SHCreateMemStream exists on Win7 but is not safe for us to use until Win8. - if forceLegacy || !wingoes.IsWin8OrGreater() { - return newMemoryStreamLegacy(initialBytes) - } - var base *byte var length uint32 if l := uint32(len(initialBytes)); l > 0 { @@ -525,32 +348,3 @@ func newMemoryStreamInternal(initialBytes []byte, forceLegacy bool) (result Stre return obj, nil } - -func newMemoryStreamLegacy(initialBytes []byte) (result Stream, _ error) { - ppstream := NewABIReceiver() - hr := createStreamOnHGlobal(internal.HGLOBAL(0), true, ppstream) - if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { - return result, e - } - - obj := result.Make(ppstream).(Stream) - - if err := obj.SetSize(uint64(len(initialBytes))); err != nil { - return result, err - } - - if len(initialBytes) == 0 { - return obj, nil - } - - _, err := obj.Write(initialBytes) - if err != nil { - return result, err - } - - if _, err := obj.Seek(0, io.SeekStart); err != nil { - return result, err - } - - return obj, nil -} diff --git a/vendor/github.com/dblohm7/wingoes/com/stream_386.go b/vendor/github.com/dblohm7/wingoes/com/stream_386.go new file mode 100644 index 0000000..6737941 --- /dev/null +++ b/vendor/github.com/dblohm7/wingoes/com/stream_386.go @@ -0,0 +1,130 @@ +// Copyright (c) 2023 Tailscale Inc & 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 windows + +package com + +import ( + "math" + "syscall" + "unsafe" + + "github.com/dblohm7/wingoes" +) + +const maxStreamRWLen = math.MaxInt32 + +func (abi *IStreamABI) Seek(offset int64, whence int) (n int64, _ error) { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[5] + + words := (*[2]uintptr)(unsafe.Pointer(&offset)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + words[0], + words[1], + uintptr(uint32(whence)), + uintptr(unsafe.Pointer(&n)), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return 0, e + } + + return n, nil +} + +func (abi *IStreamABI) SetSize(newSize uint64) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[6] + + words := (*[2]uintptr)(unsafe.Pointer(&newSize)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + words[0], + words[1], + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} + +func (abi *IStreamABI) CopyTo(dest *IStreamABI, numBytesToCopy uint64) (bytesRead, bytesWritten uint64, _ error) { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[7] + + words := (*[2]uintptr)(unsafe.Pointer(&numBytesToCopy)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(unsafe.Pointer(dest)), + words[0], + words[1], + uintptr(unsafe.Pointer(&bytesRead)), + uintptr(unsafe.Pointer(&bytesWritten)), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return bytesRead, bytesWritten, e + } + + return bytesRead, bytesWritten, nil +} + +func (abi *IStreamABI) LockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[10] + + oWords := (*[2]uintptr)(unsafe.Pointer(&offset)) + nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + oWords[0], + oWords[1], + nWords[0], + nWords[1], + uintptr(lockType), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} + +func (abi *IStreamABI) UnlockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[11] + + oWords := (*[2]uintptr)(unsafe.Pointer(&offset)) + nWords := (*[2]uintptr)(unsafe.Pointer(&numBytes)) + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + oWords[0], + oWords[1], + nWords[0], + nWords[1], + uintptr(lockType), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} diff --git a/vendor/github.com/dblohm7/wingoes/com/stream_not386.go b/vendor/github.com/dblohm7/wingoes/com/stream_not386.go index 7b82a40..a0593f6 100644 --- a/vendor/github.com/dblohm7/wingoes/com/stream_not386.go +++ b/vendor/github.com/dblohm7/wingoes/com/stream_not386.go @@ -8,6 +8,109 @@ package com import ( "math" + "syscall" + "unsafe" + + "github.com/dblohm7/wingoes" ) const maxStreamRWLen = math.MaxUint32 + +func (abi *IStreamABI) Seek(offset int64, whence int) (n int64, _ error) { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[5] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(offset), + uintptr(uint32(whence)), + uintptr(unsafe.Pointer(&n)), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return 0, e + } + + return n, nil +} + +func (abi *IStreamABI) SetSize(newSize uint64) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[6] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(newSize), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} + +func (abi *IStreamABI) CopyTo(dest *IStreamABI, numBytesToCopy uint64) (bytesRead, bytesWritten uint64, _ error) { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[7] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(unsafe.Pointer(dest)), + uintptr(numBytesToCopy), + uintptr(unsafe.Pointer(&bytesRead)), + uintptr(unsafe.Pointer(&bytesWritten)), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return bytesRead, bytesWritten, e + } + + return bytesRead, bytesWritten, nil +} + +func (abi *IStreamABI) LockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[10] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(offset), + uintptr(numBytes), + uintptr(lockType), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} + +func (abi *IStreamABI) UnlockRegion(offset, numBytes uint64, lockType LOCKTYPE) error { + var hr wingoes.HRESULT + method := unsafe.Slice(abi.Vtbl, 14)[11] + + rc, _, _ := syscall.SyscallN( + method, + uintptr(unsafe.Pointer(abi)), + uintptr(offset), + uintptr(numBytes), + uintptr(lockType), + ) + hr = wingoes.HRESULT(rc) + + if e := wingoes.ErrorFromHRESULT(hr); e.Failed() { + return e + } + + return nil +} diff --git a/vendor/github.com/dblohm7/wingoes/com/stream_test_386.go b/vendor/github.com/dblohm7/wingoes/com/stream_test_386.go new file mode 100644 index 0000000..5dfaa8f --- /dev/null +++ b/vendor/github.com/dblohm7/wingoes/com/stream_test_386.go @@ -0,0 +1,11 @@ +// Copyright (c) 2024 Tailscale Inc & 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 windows + +package com + +func getTooBigSlice() []byte { + return nil +} diff --git a/vendor/github.com/dblohm7/wingoes/com/stream_test_not386.go b/vendor/github.com/dblohm7/wingoes/com/stream_test_not386.go new file mode 100644 index 0000000..9a3db1b --- /dev/null +++ b/vendor/github.com/dblohm7/wingoes/com/stream_test_not386.go @@ -0,0 +1,11 @@ +// Copyright (c) 2024 Tailscale Inc & 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 windows && !386 + +package com + +func getTooBigSlice() []byte { + return make([]byte, maxStreamRWLen+1) +} diff --git a/vendor/github.com/dblohm7/wingoes/com/stream_windows_386.go b/vendor/github.com/dblohm7/wingoes/com/stream_windows_386.go deleted file mode 100644 index c68e24e..0000000 --- a/vendor/github.com/dblohm7/wingoes/com/stream_windows_386.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2023 Tailscale Inc & 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 com - -import ( - "math" -) - -const maxStreamRWLen = math.MaxInt32 diff --git a/vendor/github.com/dblohm7/wingoes/com/zsyscall_windows.go b/vendor/github.com/dblohm7/wingoes/com/zsyscall_windows.go index d057da5..3c72535 100644 --- a/vendor/github.com/dblohm7/wingoes/com/zsyscall_windows.go +++ b/vendor/github.com/dblohm7/wingoes/com/zsyscall_windows.go @@ -7,7 +7,6 @@ import ( "unsafe" "github.com/dblohm7/wingoes" - "github.com/dblohm7/wingoes/internal" "golang.org/x/sys/windows" ) @@ -44,63 +43,52 @@ var ( modoleaut32 = windows.NewLazySystemDLL("oleaut32.dll") modshlwapi = windows.NewLazySystemDLL("shlwapi.dll") - procCoCreateInstance = modole32.NewProc("CoCreateInstance") - procCoGetApartmentType = modole32.NewProc("CoGetApartmentType") - procCoIncrementMTAUsage = modole32.NewProc("CoIncrementMTAUsage") - procCoInitializeEx = modole32.NewProc("CoInitializeEx") - procCoInitializeSecurity = modole32.NewProc("CoInitializeSecurity") - procCreateStreamOnHGlobal = modole32.NewProc("CreateStreamOnHGlobal") - procSetOaNoCache = modoleaut32.NewProc("SetOaNoCache") - procSHCreateMemStream = modshlwapi.NewProc("SHCreateMemStream") + procCoCreateInstance = modole32.NewProc("CoCreateInstance") + procCoGetApartmentType = modole32.NewProc("CoGetApartmentType") + procCoIncrementMTAUsage = modole32.NewProc("CoIncrementMTAUsage") + procCoInitializeEx = modole32.NewProc("CoInitializeEx") + procCoInitializeSecurity = modole32.NewProc("CoInitializeSecurity") + procSetOaNoCache = modoleaut32.NewProc("SetOaNoCache") + procSHCreateMemStream = modshlwapi.NewProc("SHCreateMemStream") ) func coCreateInstance(clsid *CLSID, unkOuter *IUnknownABI, clsctx coCLSCTX, iid *IID, ppv **IUnknownABI) (hr wingoes.HRESULT) { - r0, _, _ := syscall.Syscall6(procCoCreateInstance.Addr(), 5, uintptr(unsafe.Pointer(clsid)), uintptr(unsafe.Pointer(unkOuter)), uintptr(clsctx), uintptr(unsafe.Pointer(iid)), uintptr(unsafe.Pointer(ppv)), 0) + r0, _, _ := syscall.SyscallN(procCoCreateInstance.Addr(), uintptr(unsafe.Pointer(clsid)), uintptr(unsafe.Pointer(unkOuter)), uintptr(clsctx), uintptr(unsafe.Pointer(iid)), uintptr(unsafe.Pointer(ppv))) hr = wingoes.HRESULT(r0) return } func coGetApartmentType(aptType *coAPTTYPE, qual *coAPTTYPEQUALIFIER) (hr wingoes.HRESULT) { - r0, _, _ := syscall.Syscall(procCoGetApartmentType.Addr(), 2, uintptr(unsafe.Pointer(aptType)), uintptr(unsafe.Pointer(qual)), 0) + r0, _, _ := syscall.SyscallN(procCoGetApartmentType.Addr(), uintptr(unsafe.Pointer(aptType)), uintptr(unsafe.Pointer(qual))) hr = wingoes.HRESULT(r0) return } func coIncrementMTAUsage(cookie *coMTAUsageCookie) (hr wingoes.HRESULT) { - r0, _, _ := syscall.Syscall(procCoIncrementMTAUsage.Addr(), 1, uintptr(unsafe.Pointer(cookie)), 0, 0) + r0, _, _ := syscall.SyscallN(procCoIncrementMTAUsage.Addr(), uintptr(unsafe.Pointer(cookie))) hr = wingoes.HRESULT(r0) return } func coInitializeEx(reserved uintptr, flags uint32) (hr wingoes.HRESULT) { - r0, _, _ := syscall.Syscall(procCoInitializeEx.Addr(), 2, uintptr(reserved), uintptr(flags), 0) + r0, _, _ := syscall.SyscallN(procCoInitializeEx.Addr(), uintptr(reserved), uintptr(flags)) hr = wingoes.HRESULT(r0) return } func coInitializeSecurity(sd *windows.SECURITY_DESCRIPTOR, authSvcLen int32, authSvc *soleAuthenticationService, reserved1 uintptr, authnLevel rpcAuthnLevel, impLevel rpcImpersonationLevel, authList *soleAuthenticationList, capabilities authCapabilities, reserved2 uintptr) (hr wingoes.HRESULT) { - r0, _, _ := syscall.Syscall9(procCoInitializeSecurity.Addr(), 9, uintptr(unsafe.Pointer(sd)), uintptr(authSvcLen), uintptr(unsafe.Pointer(authSvc)), uintptr(reserved1), uintptr(authnLevel), uintptr(impLevel), uintptr(unsafe.Pointer(authList)), uintptr(capabilities), uintptr(reserved2)) - hr = wingoes.HRESULT(r0) - return -} - -func createStreamOnHGlobal(hglobal internal.HGLOBAL, deleteOnRelease bool, stream **IUnknownABI) (hr wingoes.HRESULT) { - var _p0 uint32 - if deleteOnRelease { - _p0 = 1 - } - r0, _, _ := syscall.Syscall(procCreateStreamOnHGlobal.Addr(), 3, uintptr(hglobal), uintptr(_p0), uintptr(unsafe.Pointer(stream))) + r0, _, _ := syscall.SyscallN(procCoInitializeSecurity.Addr(), uintptr(unsafe.Pointer(sd)), uintptr(authSvcLen), uintptr(unsafe.Pointer(authSvc)), uintptr(reserved1), uintptr(authnLevel), uintptr(impLevel), uintptr(unsafe.Pointer(authList)), uintptr(capabilities), uintptr(reserved2)) hr = wingoes.HRESULT(r0) return } func setOaNoCache() { - syscall.Syscall(procSetOaNoCache.Addr(), 0, 0, 0, 0) + syscall.SyscallN(procSetOaNoCache.Addr()) return } func shCreateMemStream(pInit *byte, cbInit uint32) (stream *IUnknownABI) { - r0, _, _ := syscall.Syscall(procSHCreateMemStream.Addr(), 2, uintptr(unsafe.Pointer(pInit)), uintptr(cbInit), 0) + r0, _, _ := syscall.SyscallN(procSHCreateMemStream.Addr(), uintptr(unsafe.Pointer(pInit)), uintptr(cbInit)) stream = (*IUnknownABI)(unsafe.Pointer(r0)) return } diff --git a/vendor/github.com/dblohm7/wingoes/error.go b/vendor/github.com/dblohm7/wingoes/error.go index baeacad..11845ae 100644 --- a/vendor/github.com/dblohm7/wingoes/error.go +++ b/vendor/github.com/dblohm7/wingoes/error.go @@ -27,7 +27,6 @@ const ( hrE_NOTIMPL = HRESULT(-((0x80004001 ^ 0xFFFFFFFF) + 1)) hrE_POINTER = HRESULT(-((0x80004003 ^ 0xFFFFFFFF) + 1)) hrE_UNEXPECTED = HRESULT(-((0x8000FFFF ^ 0xFFFFFFFF) + 1)) - hrTYPE_E_WRONGTYPEKIND = HRESULT(-((0x8002802A ^ 0xFFFFFFFF) + 1)) ) // S_FALSE is a peculiar HRESULT value which means that the call executed @@ -83,6 +82,10 @@ func (hr HRESULT) String() string { return fmt.Sprintf("0x%08X", uint32(hr)) } +func (hr HRESULT) GoString() string { + return fmt.Sprintf("%T(0x%08X)", hr, uint32(hr)) +} + func (hr HRESULT) isNT() bool { return (hr & (hrCustomerBit | hrFacilityNTBit)) == hrFacilityNTBit } @@ -152,20 +155,26 @@ func ErrorFromHRESULT(hr HRESULT) Error { return Error(hr) } +// SupportedErrorTypes is a type constraint describing the possible types +// that may be used as inputs to [NewError]. +type SupportedErrorTypes interface { + Error | HRESULT | windows.Errno | windows.NTStatus +} + // NewError converts e into an Error if e's type is supported. It returns // both the Error and a bool indicating whether the conversion was successful. -func NewError(e any) (Error, bool) { - switch v := e.(type) { +func NewError[E SupportedErrorTypes](e E) (Error) { + switch v := any(e).(type) { case Error: - return v, true + return v case windows.NTStatus: - return ErrorFromNTStatus(v), true + return ErrorFromNTStatus(v) case windows.Errno: - return ErrorFromErrno(v), true + return ErrorFromErrno(v) case HRESULT: - return ErrorFromHRESULT(v), true + return ErrorFromHRESULT(v) default: - return ErrorFromHRESULT(hrTYPE_E_WRONGTYPEKIND), false + panic(fmt.Sprintf("Unsupported error type %T", v)) } } @@ -221,7 +230,7 @@ func (e Error) toErrno(f errnoFailHandler) windows.Errno { // AsError converts the Error to a windows.Errno, but panics if not possible. func (e Error) AsErrno() windows.Errno { handler := func(hr HRESULT) windows.Errno { - panic(fmt.Sprintf("wingoes.Error: Called AsErrno on a non-convertable HRESULT 0x%08X", uint32(hr))) + panic(fmt.Sprintf("wingoes.Error: Called AsErrno on a non-convertable %#v", hr)) return windows.ERROR_UNIDENTIFIED_ERROR } @@ -247,7 +256,7 @@ func (e Error) toNTStatus(f ntStatusFailHandler) windows.NTStatus { // AsNTStatus converts the Error to a windows.NTStatus, but panics if not possible. func (e Error) AsNTStatus() windows.NTStatus { handler := func(hr HRESULT) windows.NTStatus { - panic(fmt.Sprintf("windows.Error: Called AsNTStatus on a non-NTSTATUS HRESULT 0x%08X", uint32(hr))) + panic(fmt.Sprintf("windows.Error: Called AsNTStatus on a non-NTSTATUS %#v", hr)) return windows.STATUS_UNSUCCESSFUL } diff --git a/vendor/github.com/dblohm7/wingoes/internal/types.go b/vendor/github.com/dblohm7/wingoes/internal/types.go deleted file mode 100644 index 62fe249..0000000 --- a/vendor/github.com/dblohm7/wingoes/internal/types.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2023 Tailscale Inc & 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 windows - -package internal - -import ( - "golang.org/x/sys/windows" -) - -type HGLOBAL windows.Handle diff --git a/vendor/github.com/dblohm7/wingoes/mksyscall.go b/vendor/github.com/dblohm7/wingoes/mksyscall.go new file mode 100644 index 0000000..b79a56e --- /dev/null +++ b/vendor/github.com/dblohm7/wingoes/mksyscall.go @@ -0,0 +1,14 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build windows + +package wingoes + +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go mksyscall.go +//go:generate go run golang.org/x/tools/cmd/goimports -w zsyscall_windows.go + +// Appending a '?' to this declaration because it's very, very deprecated, in +// the (admittedly unlikely) chance it actually gets removed in a future version +// of Windows. +//sys getVersionEx(osv *_OSVERSIONINFOEX) (err error) [int32(failretval)==0] = kernel32.GetVersionExW? diff --git a/vendor/github.com/dblohm7/wingoes/osversion.go b/vendor/github.com/dblohm7/wingoes/osversion.go index 7e90d2b..e081d01 100644 --- a/vendor/github.com/dblohm7/wingoes/osversion.go +++ b/vendor/github.com/dblohm7/wingoes/osversion.go @@ -9,27 +9,33 @@ package wingoes import ( "fmt" "sync" + "sync/atomic" + "unsafe" "golang.org/x/sys/windows" "golang.org/x/sys/windows/registry" ) -var ( - verOnce sync.Once - verInfo osVersionInfo // must access via getVersionInfo() +const ( + _VER_MINORVERSION = 0x0000001 + _VER_MAJORVERSION = 0x0000002 + _VER_BUILDNUMBER = 0x0000004 + _VER_PLATFORMID = 0x0000008 + _VER_SERVICEPACKMINOR = 0x0000010 + _VER_SERVICEPACKMAJOR = 0x0000020 + _VER_SUITENAME = 0x0000040 + _VER_PRODUCT_TYPE = 0x0000080 ) -// osVersionInfo is more compact than windows.OsVersionInfoEx, which contains -// extraneous information. -type osVersionInfo struct { - major uint32 - minor uint32 - build uint32 - servicePack uint16 - str string - isDC bool - isServer bool -} +const ( + _VER_EQUAL = 1 + _VER_GREATER = 2 + _VER_GREATER_EQUAL = 3 + _VER_LESS = 4 + _VER_LESS_EQUAL = 5 + _VER_AND = 6 + _VER_OR = 7 +) const ( _VER_NT_WORKSTATION = 1 @@ -37,29 +43,124 @@ const ( _VER_NT_SERVER = 3 ) -func getVersionInfo() *osVersionInfo { - verOnce.Do(func() { - osv := windows.RtlGetVersion() - verInfo = osVersionInfo{ - major: osv.MajorVersion, - minor: osv.MinorVersion, - build: osv.BuildNumber, - servicePack: osv.ServicePackMajor, - str: fmt.Sprintf("%d.%d.%d", osv.MajorVersion, osv.MinorVersion, osv.BuildNumber), - isDC: osv.ProductType == _VER_NT_DOMAIN_CONTROLLER, +// The definition in x/sys/windows doesn't export the OSVersionInfoSize field, +// which we need to set before making API calls. +type _OSVERSIONINFOEX struct { + OSVersionInfoSize uint32 + MajorVersion uint32 + MinorVersion uint32 + BuildNumber uint32 + PlatformId uint32 + CSDVersion [128]uint16 + ServicePackMajor uint16 + ServicePackMinor uint16 + SuiteMask uint16 + ProductType byte + _ byte // Reserved +} + +type osVersionInfo struct { + fallbackBuildMin atomic.Uint32 + fallbackBuildMax atomic.Uint32 + build uint32 + str string + isDC bool + isServer bool + useFallback bool +} + +var ( + // We cannot use mksyscall for these because they pass uint64 by value on + // 32-bit CPU architectures. + procVerSetConditionMask = modkernel32.NewProc("VerSetConditionMask") + procVerifyVersionInfo = modkernel32.NewProc("VerifyVersionInfoW") + verOnce sync.Once + verInfo osVersionInfo // must access via getVersionInfo() +) + +func getVersionInfoInternal() (*_OSVERSIONINFOEX, error) { + osv := _OSVERSIONINFOEX{ + OSVersionInfoSize: uint32(unsafe.Sizeof(_OSVERSIONINFOEX{})), + } + // Using GetVersionEx to account for app manifest. + if err := getVersionEx(&osv); err != nil { + return nil, err + } + return &osv, nil +} + +func (osv *osVersionInfo) initFlags() { + if isDC, err := verQueryProductType(_VER_NT_DOMAIN_CONTROLLER); err == nil { + osv.isDC = isDC + if isDC { // Domain Controllers are also implicitly servers. - isServer: osv.ProductType == _VER_NT_DOMAIN_CONTROLLER || osv.ProductType == _VER_NT_SERVER, + osv.isServer = true + return } - // UBR is only available on Windows 10 and 11 (MajorVersion == 10). - if osv.MajorVersion == 10 { - if ubr, err := getUBR(); err == nil { - verInfo.str = fmt.Sprintf("%s.%d", verInfo.str, ubr) - } + } + + if isServer, err := verQueryProductType(_VER_NT_SERVER); err == nil { + osv.isServer = isServer + } +} + +func (osv *osVersionInfo) initFallback() { + osv.initFlags() + osv.useFallback = true +} + +func verCheckManifest(osv *_OSVERSIONINFOEX) bool { + major, minor, build := windows.RtlGetNtVersionNumbers() + return major == osv.MajorVersion && minor == osv.MinorVersion && build == osv.BuildNumber +} + +func (osv *osVersionInfo) init() { + osvx, err := getVersionInfoInternal() + if err != nil { + osv.initFallback() + return + } + + // We only support 10.0.x.x + if osvx.MajorVersion != 10 || osvx.MinorVersion != 0 { + if verCheckManifest(osvx) { + panic("change in versioning scheme -- package must be updated to interpret") + } else { + panic("incoherent Windows version -- missing/outdated manifest?") } - }) + } + + *osv = osVersionInfo{ + build: osvx.BuildNumber, + str: versionString(osvx), + isDC: osvx.ProductType == _VER_NT_DOMAIN_CONTROLLER, + // Domain Controllers are also implicitly servers. + isServer: osvx.ProductType == _VER_NT_DOMAIN_CONTROLLER || osvx.ProductType == _VER_NT_SERVER, + } +} + +func getVersionInfo() *osVersionInfo { + verOnce.Do(verInfo.init) return &verInfo } +func versionString(osv *_OSVERSIONINFOEX) string { + fmtstr := "%d.%d.%d.%d" + vers := append(make([]any, 0, 4), + uint(osv.MajorVersion), + uint(osv.MinorVersion), + uint(osv.BuildNumber), + ) + + if ubr, err := getUBR(); err == nil { + vers = append(vers, uint(ubr)) + } else { + fmtstr = fmtstr[:len(fmtstr)-3] + } + + return fmt.Sprintf(fmtstr, vers...) +} + // getUBR returns the "update build revision," ie. the fourth component of the // version string found on Windows 10 and Windows 11 systems. func getUBR() (uint32, error) { @@ -82,8 +183,7 @@ func getUBR() (uint32, error) { } // GetOSVersionString returns the Windows version of the current machine in -// dotted-decimal form. The version string contains 3 components on Windows 7 -// and 8.x, and 4 components on Windows 10 and 11. +// dotted-decimal form. func GetOSVersionString() string { return getVersionInfo().String() } @@ -100,31 +200,6 @@ func IsWinDomainController() bool { return getVersionInfo().isDC } -// IsWin7SP1OrGreater returns true when running on Windows 7 SP1 or newer. -func IsWin7SP1OrGreater() bool { - if IsWin8OrGreater() { - return true - } - - vi := getVersionInfo() - return vi.major == 6 && vi.minor == 1 && vi.servicePack > 0 -} - -// IsWin8OrGreater returns true when running on Windows 8.0 or newer. -func IsWin8OrGreater() bool { - return getVersionInfo().isVersionOrGreater(6, 2, 0) -} - -// IsWin8Point1OrGreater returns true when running on Windows 8.1 or newer. -func IsWin8Point1OrGreater() bool { - return getVersionInfo().isVersionOrGreater(6, 3, 0) -} - -// IsWin10OrGreater returns true when running on any build of Windows 10 or newer. -func IsWin10OrGreater() bool { - return getVersionInfo().major >= 10 -} - // Win10BuildConstant encodes build numbers for the various editions of Windows 10, // for use with IsWin10BuildOrGreater. type Win10BuildConstant uint32 @@ -133,6 +208,7 @@ const ( Win10BuildRTM = Win10BuildConstant(10240) Win10Build1511 = Win10BuildConstant(10586) Win10Build1607 = Win10BuildConstant(14393) + WinServer2016 = Win10Build1607 Win10BuildAnniversary = Win10Build1607 Win10Build1703 = Win10BuildConstant(15063) Win10BuildCreators = Win10Build1703 @@ -140,6 +216,7 @@ const ( Win10BuildFallCreators = Win10Build1709 Win10Build1803 = Win10BuildConstant(17134) Win10Build1809 = Win10BuildConstant(17763) + WinServer2019 = Win10Build1809 Win10Build1903 = Win10BuildConstant(18362) Win10Build1909 = Win10BuildConstant(18363) Win10Build2004 = Win10BuildConstant(19041) @@ -147,6 +224,7 @@ const ( Win10Build21H1 = Win10BuildConstant(19043) Win10Build21H2 = Win10BuildConstant(19044) Win10Build22H2 = Win10BuildConstant(19045) + WinServer2022 = Win10BuildConstant(20348) ) // IsWin10BuildOrGreater returns true when running on the specified Windows 10 @@ -163,6 +241,10 @@ const ( Win11BuildRTM = Win11BuildConstant(22000) Win11Build22H2 = Win11BuildConstant(22621) Win11Build23H2 = Win11BuildConstant(22631) + Win11Build24H2 = Win11BuildConstant(26100) + WinServer2025 = Win11Build24H2 + Win11Build25H2 = Win11BuildConstant(26200) + Win11Build26H1 = Win11BuildConstant(28000) ) // IsWin11OrGreater returns true when running on any release of Windows 11, @@ -184,16 +266,63 @@ func (osv *osVersionInfo) String() string { } func (osv *osVersionInfo) isWin10BuildOrGreater(build uint32) bool { - return osv.isVersionOrGreater(10, 0, build) + if !osv.useFallback { + return osv.build >= build + } + + if osv.fallbackBuildMin.Load() >= build { + return true + } + + if build >= osv.fallbackBuildMax.Load() { + return false + } + + result, err := verQueryBuild(10, 0, build) + if err == nil { + if result { + osv.fallbackBuildMin.Store(build) + } else { + osv.fallbackBuildMax.Store(build) + } + } + return result } -func (osv *osVersionInfo) isVersionOrGreater(major, minor, build uint32) bool { - return isVerGE(osv.major, major, osv.minor, minor, osv.build, build) +func verQueryBuild(major, minor, build uint32) (bool, error) { + var condMask uint64 + condMask = verSetConditionMask(condMask, _VER_MAJORVERSION, _VER_GREATER_EQUAL) + condMask = verSetConditionMask(condMask, _VER_MINORVERSION, _VER_GREATER_EQUAL) + condMask = verSetConditionMask(condMask, _VER_BUILDNUMBER, _VER_GREATER_EQUAL) + + typeMask := uint32(_VER_MAJORVERSION | _VER_MINORVERSION | _VER_BUILDNUMBER) + + osv := _OSVERSIONINFOEX{ + MajorVersion: major, + MinorVersion: minor, + BuildNumber: build, + } + + return verVerify(&osv, typeMask, condMask) } -func isVerGE(lmajor, rmajor, lminor, rminor, lbuild, rbuild uint32) bool { - return lmajor > rmajor || - lmajor == rmajor && - (lminor > rminor || - lminor == rminor && lbuild >= rbuild) +func verQueryProductType(wantProdType byte) (bool, error) { + condMask := verSetConditionMask(0, _VER_PRODUCT_TYPE, _VER_EQUAL) + osv := _OSVERSIONINFOEX{ + ProductType: wantProdType, + } + return verVerify(&osv, _VER_PRODUCT_TYPE, condMask) +} + +func verVerify(osv *_OSVERSIONINFOEX, typeMask uint32, condMask uint64) (bool, error) { + osv.OSVersionInfoSize = uint32(unsafe.Sizeof(_OSVERSIONINFOEX{})) + err := verifyVersionInfo(osv, typeMask, condMask) + switch err { + case nil: + return true, nil + case windows.ERROR_OLD_WIN_VERSION: + return false, nil + default: + return false, err + } } diff --git a/vendor/github.com/dblohm7/wingoes/osversion_386.go b/vendor/github.com/dblohm7/wingoes/osversion_386.go new file mode 100644 index 0000000..e96ca5d --- /dev/null +++ b/vendor/github.com/dblohm7/wingoes/osversion_386.go @@ -0,0 +1,38 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build windows + +package wingoes + +import ( + "syscall" + "unsafe" +) + +func verSetConditionMask(conditionMask uint64, typeMask uint32, condition byte) uint64 { + words := (*[2]uintptr)(unsafe.Pointer(&conditionMask)) + r0, r1, _ := syscall.SyscallN( + procVerSetConditionMask.Addr(), + words[0], + words[1], + uintptr(typeMask), + uintptr(condition), + ) + return uint64(r0) | (uint64(r1) << 32) +} + +func verifyVersionInfo(versionInformation *_OSVERSIONINFOEX, typeMask uint32, conditionMask uint64) (err error) { + words := (*[2]uintptr)(unsafe.Pointer(&conditionMask)) + rc, _, e := syscall.SyscallN( + procVerifyVersionInfo.Addr(), + uintptr(unsafe.Pointer(versionInformation)), + uintptr(typeMask), + words[0], + words[1], + ) + if int32(rc) == 0 { + err = e + } + return err +} diff --git a/vendor/github.com/dblohm7/wingoes/osversion_not386.go b/vendor/github.com/dblohm7/wingoes/osversion_not386.go new file mode 100644 index 0000000..295f3b6 --- /dev/null +++ b/vendor/github.com/dblohm7/wingoes/osversion_not386.go @@ -0,0 +1,34 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build windows && !386 + +package wingoes + +import ( + "syscall" + "unsafe" +) + +func verSetConditionMask(conditionMask uint64, typeMask uint32, condition byte) uint64 { + r0, _, _ := syscall.SyscallN( + procVerSetConditionMask.Addr(), + uintptr(conditionMask), + uintptr(typeMask), + uintptr(condition), + ) + return uint64(r0) +} + +func verifyVersionInfo(versionInformation *_OSVERSIONINFOEX, typeMask uint32, conditionMask uint64) (err error) { + rc, _, e := syscall.SyscallN( + procVerifyVersionInfo.Addr(), + uintptr(unsafe.Pointer(versionInformation)), + uintptr(typeMask), + uintptr(conditionMask), + ) + if int32(rc) == 0 { + err = e + } + return err +} diff --git a/vendor/github.com/dblohm7/wingoes/pe/pe.go b/vendor/github.com/dblohm7/wingoes/pe/pe.go index db46bec..0822b45 100644 --- a/vendor/github.com/dblohm7/wingoes/pe/pe.go +++ b/vendor/github.com/dblohm7/wingoes/pe/pe.go @@ -13,6 +13,7 @@ import ( "errors" "fmt" "io" + "math" "math/bits" "os" "reflect" @@ -83,10 +84,14 @@ func (s *SectionHeader) NameString() string { return string(s.Name[:]) } -type peReader interface { - io.Closer +type peReaderBase interface { io.ReaderAt io.ReadSeeker +} + +type peReader interface { + peReaderBase + io.Closer Base() uintptr Limit() uintptr } @@ -136,7 +141,7 @@ func checkMagic(oh OptionalHeader, machine uint16) bool { case dpe.IMAGE_FILE_MACHINE_AMD64, dpe.IMAGE_FILE_MACHINE_ARM64: expectedMagic = 0x020B default: - panic("unsupported machine") + panic(fmt.Sprintf("unsupported machine 0x%04X", machine)) } return oh.GetMagic() == expectedMagic @@ -147,22 +152,32 @@ type peBounds struct { limit uintptr } +func (peb *peBounds) Base() uintptr { + return peb.base +} + +func (peb *peBounds) Limit() uintptr { + return peb.limit +} + type peFile struct { - *os.File + peReaderBase peBounds } -func (pef *peFile) Base() uintptr { - return pef.base -} +func (pef *peFile) Close() error { + if pef.peReaderBase == nil { + return nil + } -func (pef *peFile) Limit() uintptr { - if pef.limit == 0 { - if fi, err := pef.Stat(); err == nil { - pef.limit = uintptr(fi.Size()) + if cl, ok := pef.peReaderBase.(io.Closer); ok { + if err := cl.Close(); err != nil { + return err } } - return pef.limit + + pef.peReaderBase = nil + return nil } type peModule struct { @@ -171,14 +186,6 @@ type peModule struct { modLock uintptr } -func (pei *peModule) Base() uintptr { - return pei.base -} - -func (pei *peModule) Limit() uintptr { - return pei.limit -} - // NewPEFromFileName opens a PE binary located at filename and parses its PE // headers. Upon success it returns a non-nil *PEHeaders, otherwise it returns a // nil *PEHeaders and a non-nil error. @@ -193,8 +200,18 @@ func NewPEFromFileName(filename string) (*PEHeaders, error) { } func newPEFromFile(f *os.File) (*PEHeaders, error) { - // peBounds base is 0, limit is loaded lazily - pef := &peFile{File: f} + fi, err := f.Stat() + if err != nil { + f.Close() + return nil, err + } + + return newPEFromReaderBase(f, uintptr(fi.Size())) +} + +func newPEFromReaderBase(rb peReaderBase, size uintptr) (*PEHeaders, error) { + // peBounds base is 0, limit is size + pef := &peFile{peReaderBase: rb, peBounds: peBounds{limit: size}} peh, err := loadHeaders(pef) if err != nil { pef.Close() @@ -204,6 +221,15 @@ func newPEFromFile(f *os.File) (*PEHeaders, error) { return peh, nil } +// NewPEFromBlob parses the headers from contents of a PE file stored in blob. +// The blob must contain the contents of a file, not a module. Upon success it +// returns a non-nil *PEHeaders, otherwise it returns a nil *PEHeaders and a +// non-nil error. +// Call Close() on the returned *PEHeaders when it is no longer needed. +func NewPEFromBlob(blob []byte) (*PEHeaders, error) { + return newPEFromReaderBase(bytes.NewReader(blob), uintptr(len(blob))) +} + // Close frees any resources that were opened when peh was created. func (peh *PEHeaders) Close() error { return peh.r.Close() @@ -213,17 +239,20 @@ type rvaType interface { ~int8 | ~int16 | ~int32 | ~uint8 | ~uint16 | ~uint32 } -// addOffset ensures that, if off is negative, it does not underflow base. -func addOffset[O rvaType](base uintptr, off O) uintptr { +// addOffset ensures that off neither overflows nor underflows base. +func addOffset[O rvaType](base uintptr, off O) (addr uintptr, ok bool) { if off >= 0 { - return base + uintptr(off) + if upoff := uintptr(off); upoff <= (math.MaxUint - base) { + return base + upoff, true + } + return 0, false } negation := uintptr(-off) if negation >= base { - return 0 + return 0, false } - return base - negation + return base - negation, true } func binaryRead(r io.Reader, data any) (err error) { @@ -254,9 +283,12 @@ func readStruct[T any, R rvaType](r peReader, rva R) (*T, error) { return result, nil case *peModule: - addr := addOffset(r.Base(), rva) - szT := unsafe.Sizeof(*((*T)(nil))) - if addr+szT >= v.Limit() { + addr, ok := addOffset(r.Base(), rva) + if !ok { + return nil, ErrInvalidBinary + } + szT := uint32(unsafe.Sizeof(*((*T)(nil)))) + if addr2, ok := addOffset(addr, szT); !ok || addr2 >= v.Limit() { return nil, ErrInvalidBinary } @@ -285,9 +317,12 @@ func readStructArray[T any, R rvaType](r peReader, rva R, count int) ([]T, error return result, nil case *peModule: - addr := addOffset(r.Base(), rva) - szT := reflect.ArrayOf(count, reflect.TypeOf((*T)(nil)).Elem()).Size() - if addr+szT >= v.Limit() { + addr, ok := addOffset(r.Base(), rva) + if !ok { + return nil, ErrInvalidBinary + } + szT := uint32(reflect.ArrayOf(count, reflect.TypeFor[T]()).Size()) + if addr2, ok := addOffset(addr, szT); !ok || addr2 >= v.Limit() { return nil, ErrInvalidBinary } @@ -330,7 +365,7 @@ func loadHeaders(r peReader) (*PEHeaders, error) { if e_lfanew <= 0 { return nil, ErrInvalidBinary } - if addOffset(r.Base(), e_lfanew) >= r.Limit() { + if addr, ok := addOffset(r.Base(), e_lfanew); !ok || addr >= r.Limit() { return nil, ErrInvalidBinary } @@ -352,7 +387,7 @@ func loadHeaders(r peReader) (*PEHeaders, error) { // Read the file header fileHeaderOffset := uint32(e_lfanew) + uint32(unsafe.Sizeof(pe)) - if r.Base()+uintptr(fileHeaderOffset) >= r.Limit() { + if addr, ok := addOffset(r.Base(), fileHeaderOffset); !ok || addr >= r.Limit() { return nil, ErrInvalidBinary } @@ -368,7 +403,7 @@ func loadHeaders(r peReader) (*PEHeaders, error) { // Read the optional header optionalHeaderOffset := uint32(fileHeaderOffset) + uint32(unsafe.Sizeof(*fileHeader)) - if r.Base()+uintptr(optionalHeaderOffset) >= r.Limit() { + if addr, ok := addOffset(r.Base(), optionalHeaderOffset); !ok || addr >= r.Limit() { return nil, ErrInvalidBinary } @@ -402,7 +437,7 @@ func loadHeaders(r peReader) (*PEHeaders, error) { // Read in the section table sectionTableOffset := optionalHeaderOffset + uint32(fileHeader.SizeOfOptionalHeader) - if r.Base()+uintptr(sectionTableOffset) >= r.Limit() { + if addr, ok := addOffset(r.Base(), sectionTableOffset); !ok || addr >= r.Limit() { return nil, ErrInvalidBinary } @@ -474,6 +509,8 @@ const ( IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = DataDirectoryIndex(dpe.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR) ) +const _IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 + // DataDirectoryEntry returns information from nfo's data directory at index idx. // The type of the return value depends on the value of idx. Most values for idx // currently return the DataDirectoryEntry itself, however it will return more @@ -486,9 +523,13 @@ const ( // sophisticated return values, so be careful to structure your type assertions // accordingly. func (nfo *PEHeaders) DataDirectoryEntry(idx DataDirectoryIndex) (any, error) { + if ii := int(idx); ii < 0 || ii >= _IMAGE_NUMBEROF_DIRECTORY_ENTRIES { + return nil, ErrIndexOutOfRange + } + dd := nfo.optionalHeader.GetDataDirectory() if int(idx) >= len(dd) { - return nil, ErrIndexOutOfRange + return nil, ErrNotPresent } dde := dd[idx] diff --git a/vendor/github.com/dblohm7/wingoes/pe/pe_windows.go b/vendor/github.com/dblohm7/wingoes/pe/pe_windows.go index 2c6190c..17a3329 100644 --- a/vendor/github.com/dblohm7/wingoes/pe/pe_windows.go +++ b/vendor/github.com/dblohm7/wingoes/pe/pe_windows.go @@ -13,7 +13,17 @@ import ( ) func (pei *peModule) Close() error { - return windows.FreeLibrary(windows.Handle(pei.modLock)) + if pei.modLock == 0 { + return nil + } + + if err := windows.FreeLibrary(windows.Handle(pei.modLock)); err != nil { + return err + } + + pei.Reader = nil + pei.modLock = 0 + return nil } // NewPEFromBaseAddressAndSize parses the headers in a PE binary loaded @@ -22,6 +32,10 @@ func (pei *peModule) Close() error { // Upon success it returns a non-nil *PEHeaders, otherwise it returns a nil // *PEHeaders and a non-nil error. func NewPEFromBaseAddressAndSize(baseAddr uintptr, size uint32) (*PEHeaders, error) { + if baseAddr == 0 || size == 0 { + return nil, os.ErrInvalid + } + // Grab a strong reference to the module until we're done with it. var modLock windows.Handle if err := windows.GetModuleHandleEx( diff --git a/vendor/github.com/dblohm7/wingoes/pe/version.go b/vendor/github.com/dblohm7/wingoes/pe/version.go index e6a6832..f6c6982 100644 --- a/vendor/github.com/dblohm7/wingoes/pe/version.go +++ b/vendor/github.com/dblohm7/wingoes/pe/version.go @@ -48,7 +48,6 @@ const ( langEnUS = 0x0409 codePageUTF16LE = 0x04B0 langNeutral = 0 - codePageNeutral = 0 ) // NewVersionInfo extracts any VERSIONINFO resource from filepath, parses its @@ -111,7 +110,7 @@ func (vi *VersionInfo) maybeLoadTranslationIDs() { }, langAndCodePage{ language: langNeutral, - codePage: codePageNeutral, + codePage: codePageUTF16LE, }, } diff --git a/vendor/github.com/dblohm7/wingoes/time.go b/vendor/github.com/dblohm7/wingoes/time.go index e29a7f1..5598aad 100644 --- a/vendor/github.com/dblohm7/wingoes/time.go +++ b/vendor/github.com/dblohm7/wingoes/time.go @@ -8,11 +8,15 @@ package wingoes import ( "errors" + "math" "time" "golang.org/x/sys/windows" ) +// Infinite is the [time.Duration] equivalent of [windows.INFINITE]. +const Infinite = time.Duration(math.MaxInt64) + var ( // ErrDurationOutOfRange means that a time.Duration is too large to be able // to be specified as a valid Win32 timeout value. @@ -21,6 +25,10 @@ var ( // DurationToTimeoutMilliseconds converts d into a timeout usable by Win32 APIs. func DurationToTimeoutMilliseconds(d time.Duration) (uint32, error) { + if d == Infinite { + return windows.INFINITE, nil + } + millis := d.Milliseconds() if millis >= windows.INFINITE { return 0, ErrDurationOutOfRange diff --git a/vendor/github.com/dblohm7/wingoes/util.go b/vendor/github.com/dblohm7/wingoes/util.go index 658f68a..6af76af 100644 --- a/vendor/github.com/dblohm7/wingoes/util.go +++ b/vendor/github.com/dblohm7/wingoes/util.go @@ -7,9 +7,14 @@ package wingoes import ( + "fmt" + "os" + "strings" + "unicode/utf16" "unsafe" "golang.org/x/sys/windows" + _ "golang.org/x/sys/windows/registry" ) // UserSIDs contains pointers to the SIDs for a user and their primary group. @@ -78,3 +83,61 @@ func getTokenInfoFixedLen[T any](token windows.Token, infoClass uint32) (result err := windows.GetTokenInformation(token, infoClass, (*byte)(unsafe.Pointer(&result)), uint32(unsafe.Sizeof(result)), &actualLen) return result, err } + +// MultiSZDecode decodes a UTF-16 buffer containing either a [registry.MULTI_SZ] +// value or a Win32 environment block, and returns the contents as a slice of +// strings. It returns an empty slice if the value is empty, or nil if buf +// cannot be decoded. +func MultiSZDecode(buf []uint16) []string { + if buf == nil { + // Technically an empty value, but not a failure. + return []string{} + } + + const doubleNulLen = 2 + if len(buf) < doubleNulLen { + return nil + } + + // We cannot rely on the len(buf) to determine the end of the data; registry + // APIs treat MULTI_SZ strings as double-nul-terminated C-style strings. + doubleNulIdx := int(-1) + fl := len(buf) - 1 + for i, v := range buf { + if v == 0 && i < fl && buf[i+1] == 0 { + doubleNulIdx = i + break + } + } + if doubleNulIdx < 0 { + return nil + } + + str := string(utf16.Decode(buf[:doubleNulIdx])) + if len(str) == 0 { + // Technically an empty value, but not a failure. + return []string{} + } + + return strings.Split(str, "\x00") +} + +// MultiSZEncode encodes strs into the format utilized by [registry.MULTI_SZ] +// values and Win32 environment blocks. strs may be nil or empty, but it must +// not contain any empty strings. +func MultiSZEncode(strs []string) ([]uint16, error) { + var buf strings.Builder + for _, v := range strs { + if len(v) == 0 { + return nil, fmt.Errorf("MultiSZEncode: %w: empty strings not permitted", os.ErrInvalid) + } + buf.WriteString(v) + buf.WriteByte(0) + } + if buf.Len() == 0 { + // So that we end with a double-nul in the empty case + buf.WriteByte(0) + } + buf.WriteByte(0) + return utf16.Encode([]rune(buf.String())), nil +} diff --git a/vendor/github.com/dblohm7/wingoes/zsyscall_windows.go b/vendor/github.com/dblohm7/wingoes/zsyscall_windows.go new file mode 100644 index 0000000..3dc5276 --- /dev/null +++ b/vendor/github.com/dblohm7/wingoes/zsyscall_windows.go @@ -0,0 +1,56 @@ +// Code generated by 'go generate'; DO NOT EDIT. + +package wingoes + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +var _ unsafe.Pointer + +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return errERROR_EINVAL + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + +var ( + modkernel32 = windows.NewLazySystemDLL("kernel32.dll") + + procGetVersionExW = modkernel32.NewProc("GetVersionExW") +) + +func getVersionEx(osv *_OSVERSIONINFOEX) (err error) { + err = procGetVersionExW.Find() + if err != nil { + return + } + r1, _, e1 := syscall.SyscallN(procGetVersionExW.Addr(), uintptr(unsafe.Pointer(osv))) + if int32(r1) == 0 { + err = errnoErr(e1) + } + return +} diff --git a/vendor/github.com/fxamacker/cbor/v2/.golangci.yml b/vendor/github.com/fxamacker/cbor/v2/.golangci.yml index 38cb9ae..08081fb 100644 --- a/vendor/github.com/fxamacker/cbor/v2/.golangci.yml +++ b/vendor/github.com/fxamacker/cbor/v2/.golangci.yml @@ -1,104 +1,116 @@ -# Do not delete linter settings. Linters like gocritic can be enabled on the command line. - -linters-settings: - depguard: - rules: - prevent_unmaintained_packages: - list-mode: strict - files: - - $all - - "!$test" - allow: - - $gostd - - github.com/x448/float16 - deny: - - pkg: io/ioutil - desc: "replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil" - dupl: - threshold: 100 - funlen: - lines: 100 - statements: 50 - goconst: - ignore-tests: true - min-len: 2 - min-occurrences: 3 - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - disabled-checks: - - commentedOutCode - - dupImport # https://github.com/go-critic/go-critic/issues/845 - - ifElseChain - - octalLiteral - - paramTypeCombine - - whyNoLint - gofmt: - simplify: false - goimports: - local-prefixes: github.com/fxamacker/cbor - golint: - min-confidence: 0 - govet: - check-shadowing: true - lll: - line-length: 140 - maligned: - suggest-new: true - misspell: - locale: US - staticcheck: - checks: ["all"] - +version: "2" linters: - disable-all: true + default: none enable: - asciicheck - bidichk - depguard - errcheck - - exportloopref + - forbidigo - goconst - gocritic - gocyclo - - gofmt - - goimports - goprintffuncname - gosec - - gosimple - govet - ineffassign - misspell - nilerr - revive - staticcheck - - stylecheck - - typecheck - unconvert - unused - + settings: + depguard: + rules: + prevent_unmaintained_packages: + list-mode: strict + files: + - $all + - '!$test' + allow: + - $gostd + - github.com/x448/float16 + deny: + - pkg: io/ioutil + desc: 'replaced by io and os packages since Go 1.16: https://tip.golang.org/doc/go1.16#ioutil' + dupl: + threshold: 100 + funlen: + lines: 100 + statements: 50 + goconst: + min-len: 2 + min-occurrences: 3 + gocritic: + disabled-checks: + - commentedOutCode + - dupImport + - ifElseChain + - octalLiteral + - paramTypeCombine + - whyNoLint + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + govet: + enable: + - shadow + lll: + line-length: 140 + misspell: + locale: US + staticcheck: + checks: + - all + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - path: decode.go + text: string ` overflows ` has (\d+) occurrences, make it a constant + - path: decode.go + text: string ` \(range is \[` has (\d+) occurrences, make it a constant + - path: decode.go + text: string `, ` has (\d+) occurrences, make it a constant + - path: decode.go + text: string ` overflows Go's int64` has (\d+) occurrences, make it a constant + - path: decode.go + text: string `\]\)` has (\d+) occurrences, make it a constant + - path: valid.go + text: string ` for type ` has (\d+) occurrences, make it a constant + - path: valid.go + text: 'string `cbor: ` has (\d+) occurrences, make it a constant' + - linters: + - goconst + path: (.+)_test\.go + paths: + - third_party$ + - builtin$ + - examples$ issues: - # max-issues-per-linter default is 50. Set to 0 to disable limit. max-issues-per-linter: 0 - # max-same-issues default is 3. Set to 0 to disable limit. max-same-issues: 0 - - exclude-rules: - - path: decode.go - text: "string ` overflows ` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string ` \\(range is \\[` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string `, ` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string ` overflows Go's int64` has (\\d+) occurrences, make it a constant" - - path: decode.go - text: "string `\\]\\)` has (\\d+) occurrences, make it a constant" - - path: valid.go - text: "string ` for type ` has (\\d+) occurrences, make it a constant" - - path: valid.go - text: "string `cbor: ` has (\\d+) occurrences, make it a constant" +formatters: + enable: + - gofmt + - goimports + settings: + gofmt: + simplify: false + goimports: + local-prefixes: + - github.com/fxamacker/cbor + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/vendor/github.com/fxamacker/cbor/v2/README.md b/vendor/github.com/fxamacker/cbor/v2/README.md index d072b81..7aca561 100644 --- a/vendor/github.com/fxamacker/cbor/v2/README.md +++ b/vendor/github.com/fxamacker/cbor/v2/README.md @@ -683,7 +683,7 @@ because RFC 8949 treats CBOR data item with remaining bytes as malformed. Other useful functions: - `Diagnose`, `DiagnoseFirst` produce human-readable [Extended Diagnostic Notation](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G) from CBOR data. - `UnmarshalFirst` decodes first CBOR data item and return any remaining bytes. -- `Wellformed` returns true if the CBOR data item is well-formed. +- `Wellformed` returns nil error if the CBOR data item is well-formed. Interfaces identical or comparable to Go `encoding` packages include: `Marshaler`, `Unmarshaler`, `BinaryMarshaler`, and `BinaryUnmarshaler`. @@ -702,28 +702,29 @@ Default limits may need to be increased for systems handling very large data (e. ## Status -[v2.9.0](https://github.com/fxamacker/cbor/releases/tag/v2.9.0) (Jul 13, 2025) improved interoperability/transcoding between CBOR & JSON, refactored tests, and improved docs. -- Add opt-in support for `encoding.TextMarshaler` and `encoding.TextUnmarshaler` to encode and decode from CBOR text string. -- Add opt-in support for `json.Marshaler` and `json.Unmarshaler` via user-provided transcoding function. -- Update docs for TimeMode, Tag, RawTag, and add example for Embedded JSON Tag for CBOR. +v2.9.2 (Sunday, May 3, 2026) refactors and hardens the streaming encoder by adding stricter checks for encoding to CBOR indefinite-length data. This prevents improper use of this library from producing malformed CBOR indefinite-length data that would be rejected by the decoder. -v2.9.0 passed fuzz tests and is production quality. +This release includes other bugfixes, defensive checks, and added more tests. -The minimum version of Go required to build: -- v2.8.0 and newer releases require go 1.20+. -- v2.7.1 and older releases require go 1.17+. +v2.9.2 passed fuzz tests (billions of executions) and is production quality. -For more details, see [release notes](https://github.com/fxamacker/cbor/releases). +For more details, see [v2.9.2 release notes](https://github.com/fxamacker/cbor/releases). ### Prior Releases -[v2.8.0](https://github.com/fxamacker/cbor/releases/tag/v2.8.0) (March 30, 2025) is a small release primarily to add `omitzero` option to struct field tags and fix bugs. It passed fuzz tests (billions of executions) and is production quality. +Releases and commits tend to be on Sundays because my work schedule didn't leave time to work on this during weekdays (sometimes consecutive weekends and consecutive Christmas breaks, too). Monday morning releases were to allow more fuzzing to run overnight before clicking the release button. -[v2.7.0](https://github.com/fxamacker/cbor/releases/tag/v2.7.0) (June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality. +[v2.9.1](https://github.com/fxamacker/cbor/releases/tag/v2.9.1) (Monday, Mar 30, 2026) includes important bugfixes, defensive checks, improved code quality, and more tests. Although not public, the fuzzer was also improved by adding more fuzz tests. It passed fuzz tests (billions of executions) and is production quality. -[v2.6.0](https://github.com/fxamacker/cbor/releases/tag/v2.6.0) (February 2024) adds important new features, optimizations, and bug fixes. It is especially useful to systems that need to convert data between CBOR and JSON. New options and optimizations improve handling of bignum, integers, maps, and strings. +[v2.9.0](https://github.com/fxamacker/cbor/releases/tag/v2.9.0) (Sunday, Jul 13, 2025) improved interoperability/transcoding between CBOR & JSON, refactored tests, and improved docs. It passed fuzz tests (billions of executions) and is production quality. -[v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) was released on Sunday, August 13, 2023 with new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023). +[v2.8.0](https://github.com/fxamacker/cbor/releases/tag/v2.8.0) (Sunday, March 30, 2025) is a small release primarily to add `omitzero` option to struct field tags and fix bugs. It passed fuzz tests (billions of executions) and is production quality. + +[v2.7.0](https://github.com/fxamacker/cbor/releases/tag/v2.7.0) (Monday, June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality. + +[v2.6.0](https://github.com/fxamacker/cbor/releases/tag/v2.6.0) (Sunday, Feb 11, 2024) adds important new features, optimizations, and bug fixes. It is especially useful to systems that need to convert data between CBOR and JSON. New options and optimizations improve handling of bignum, integers, maps, and strings. + +[v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Sunday, August 13, 2023) adds new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023). __IMPORTANT__: 👉 Before upgrading from v2.4 or older release, please read the notable changes highlighted in the release notes. v2.5.0 is a large release with bug fixes to error handling for extraneous data in `Unmarshal`, etc. that should be reviewed before upgrading. diff --git a/vendor/github.com/fxamacker/cbor/v2/cache.go b/vendor/github.com/fxamacker/cbor/v2/cache.go index 5051f11..5743f3e 100644 --- a/vendor/github.com/fxamacker/cbor/v2/cache.go +++ b/vendor/github.com/fxamacker/cbor/v2/cache.go @@ -92,94 +92,126 @@ func newTypeInfo(t reflect.Type) *typeInfo { } type decodingStructType struct { - fields fields - fieldIndicesByName map[string]int - err error - toArray bool + fields decodingFields + fieldIndicesByName map[string]int // Only populated if toArray is false + fieldIndicesByIntKey map[int64]int // Only populated if toArray is false + err error + toArray bool } -// The stdlib errors.Join was introduced in Go 1.20, and we still support Go 1.17, so instead, -// here's a very basic implementation of an aggregated error. -type multierror []error - -func (m multierror) Error() string { - var sb strings.Builder - for i, err := range m { - sb.WriteString(err.Error()) - if i < len(m)-1 { - sb.WriteString(", ") - } - } - return sb.String() -} - -func getDecodingStructType(t reflect.Type) *decodingStructType { +func getDecodingStructType(t reflect.Type) (*decodingStructType, error) { if v, _ := decodingStructTypeCache.Load(t); v != nil { - return v.(*decodingStructType) + structType := v.(*decodingStructType) + if structType.err != nil { + return nil, structType.err + } + return structType, nil } flds, structOptions := getFields(t) toArray := hasToArrayOption(structOptions) - var errs []error - for i := 0; i < len(flds); i++ { - if flds[i].keyAsInt { - nameAsInt, numErr := strconv.Atoi(flds[i].name) - if numErr != nil { - errs = append(errs, errors.New("cbor: failed to parse field name \""+flds[i].name+"\" to int ("+numErr.Error()+")")) - break - } - flds[i].nameAsInt = int64(nameAsInt) - } - - flds[i].typInfo = getTypeInfo(flds[i].typ) + if toArray { + return getDecodingStructToArrayType(t, flds) } fieldIndicesByName := make(map[string]int, len(flds)) - for i, fld := range flds { - if _, ok := fieldIndicesByName[fld.name]; ok { - errs = append(errs, fmt.Errorf("cbor: two or more fields of %v have the same name %q", t, fld.name)) - continue - } - fieldIndicesByName[fld.name] = i - } + var fieldIndicesByIntKey map[int64]int - var err error - { - var multi multierror - for _, each := range errs { - if each != nil { - multi = append(multi, each) + decFlds := make(decodingFields, len(flds)) + for i, f := range flds { + // nameAsInt is set in getFields() except for fields with an unparsable tagged name. + // Atoi() is called here to catch and save parsing errors. + if f.keyAsInt && f.nameAsInt == 0 { + if _, numErr := strconv.Atoi(f.name); numErr != nil { + structType := &decodingStructType{ + err: errors.New("cbor: failed to parse field name \"" + f.name + "\" to int (" + numErr.Error() + ")"), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err } } - if len(multi) == 1 { - err = multi[0] - } else if len(multi) > 1 { - err = multi + + if f.keyAsInt { + if fieldIndicesByIntKey == nil { + fieldIndicesByIntKey = make(map[int64]int, len(flds)) + } + // The duplication check is only a safeguard, since getFields() already deduplicates fields. + if _, ok := fieldIndicesByIntKey[f.nameAsInt]; ok { + structType := &decodingStructType{ + err: fmt.Errorf("cbor: two or more fields of %v have the same keyasint value %d", t, f.nameAsInt), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err + } + fieldIndicesByIntKey[f.nameAsInt] = i + } else { + // The duplication check is only a safeguard, since getFields() already deduplicates fields. + if _, ok := fieldIndicesByName[f.name]; ok { + structType := &decodingStructType{ + err: fmt.Errorf("cbor: two or more fields of %v have the same name %q", t, f.name), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err + } + fieldIndicesByName[f.name] = i + } + + decFlds[i] = &decodingField{ + field: *f, + typInfo: getTypeInfo(f.typ), } } structType := &decodingStructType{ - fields: flds, - fieldIndicesByName: fieldIndicesByName, - err: err, - toArray: toArray, + fields: decFlds, + fieldIndicesByName: fieldIndicesByName, + fieldIndicesByIntKey: fieldIndicesByIntKey, } decodingStructTypeCache.Store(t, structType) - return structType + return structType, nil +} + +func getDecodingStructToArrayType(t reflect.Type, flds fields) (*decodingStructType, error) { + decFlds := make(decodingFields, len(flds)) + for i, f := range flds { + // nameAsInt is set in getFields() except for fields with an unparsable tagged name. + // Atoi() is called here to catch and save parsing errors. + if f.keyAsInt && f.nameAsInt == 0 { + if _, numErr := strconv.Atoi(f.name); numErr != nil { + structType := &decodingStructType{ + err: errors.New("cbor: failed to parse field name \"" + f.name + "\" to int (" + numErr.Error() + ")"), + } + decodingStructTypeCache.Store(t, structType) + return nil, structType.err + } + } + + decFlds[i] = &decodingField{ + field: *f, + typInfo: getTypeInfo(f.typ), + } + } + + structType := &decodingStructType{ + fields: decFlds, + toArray: true, + } + decodingStructTypeCache.Store(t, structType) + return structType, nil } type encodingStructType struct { - fields fields - bytewiseFields fields - lengthFirstFields fields - omitEmptyFieldsIdx []int + fields encodingFields + bytewiseFields encodingFields // Only populated if toArray is false + lengthFirstFields encodingFields // Only populated if toArray is false + omitEmptyFieldsIdx []int // Only populated if toArray is false err error toArray bool } -func (st *encodingStructType) getFields(em *encMode) fields { +func (st *encodingStructType) getFields(em *encMode) encodingFields { switch em.sort { case SortNone, SortFastShuffle: return st.fields @@ -191,7 +223,7 @@ func (st *encodingStructType) getFields(em *encMode) fields { } type bytewiseFieldSorter struct { - fields fields + fields encodingFields } func (x *bytewiseFieldSorter) Len() int { @@ -203,11 +235,11 @@ func (x *bytewiseFieldSorter) Swap(i, j int) { } func (x *bytewiseFieldSorter) Less(i, j int) bool { - return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) <= 0 + return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) < 0 } type lengthFirstFieldSorter struct { - fields fields + fields encodingFields } func (x *lengthFirstFieldSorter) Len() int { @@ -222,13 +254,16 @@ func (x *lengthFirstFieldSorter) Less(i, j int) bool { if len(x.fields[i].cborName) != len(x.fields[j].cborName) { return len(x.fields[i].cborName) < len(x.fields[j].cborName) } - return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) <= 0 + return bytes.Compare(x.fields[i].cborName, x.fields[j].cborName) < 0 } func getEncodingStructType(t reflect.Type) (*encodingStructType, error) { if v, _ := encodingStructTypeCache.Load(t); v != nil { structType := v.(*encodingStructType) - return structType, structType.err + if structType.err != nil { + return nil, structType.err + } + return structType, nil } flds, structOptions := getFields(t) @@ -237,111 +272,119 @@ func getEncodingStructType(t reflect.Type) (*encodingStructType, error) { return getEncodingStructToArrayType(t, flds) } - var err error var hasKeyAsInt bool var hasKeyAsStr bool var omitEmptyIdx []int + + encFlds := make(encodingFields, len(flds)) + e := getEncodeBuffer() - for i := 0; i < len(flds); i++ { + defer putEncodeBuffer(e) + + for i, f := range flds { + encFlds[i] = &encodingField{field: *f} + ef := encFlds[i] + // Get field's encodeFunc - flds[i].ef, flds[i].ief, flds[i].izf = getEncodeFunc(flds[i].typ) - if flds[i].ef == nil { - err = &UnsupportedTypeError{t} - break + ef.ef, ef.ief, ef.izf = getEncodeFunc(f.typ) + if ef.ef == nil { + structType := &encodingStructType{err: &UnsupportedTypeError{t}} + encodingStructTypeCache.Store(t, structType) + return nil, structType.err } // Encode field name - if flds[i].keyAsInt { - nameAsInt, numErr := strconv.Atoi(flds[i].name) - if numErr != nil { - err = errors.New("cbor: failed to parse field name \"" + flds[i].name + "\" to int (" + numErr.Error() + ")") - break + if f.keyAsInt { + if f.nameAsInt == 0 { + // nameAsInt is set in getFields() except for fields with an unparsable tagged name. + // Atoi() is called here to catch and save parsing errors. + if _, numErr := strconv.Atoi(f.name); numErr != nil { + structType := &encodingStructType{ + err: errors.New("cbor: failed to parse field name \"" + f.name + "\" to int (" + numErr.Error() + ")"), + } + encodingStructTypeCache.Store(t, structType) + return nil, structType.err + } } - flds[i].nameAsInt = int64(nameAsInt) + nameAsInt := f.nameAsInt if nameAsInt >= 0 { - encodeHead(e, byte(cborTypePositiveInt), uint64(nameAsInt)) + encodeHead(e, byte(cborTypePositiveInt), uint64(nameAsInt)) //nolint:gosec } else { n := nameAsInt*(-1) - 1 - encodeHead(e, byte(cborTypeNegativeInt), uint64(n)) + encodeHead(e, byte(cborTypeNegativeInt), uint64(n)) //nolint:gosec } - flds[i].cborName = make([]byte, e.Len()) - copy(flds[i].cborName, e.Bytes()) + ef.cborName = make([]byte, e.Len()) + copy(ef.cborName, e.Bytes()) e.Reset() hasKeyAsInt = true } else { - encodeHead(e, byte(cborTypeTextString), uint64(len(flds[i].name))) - flds[i].cborName = make([]byte, e.Len()+len(flds[i].name)) - n := copy(flds[i].cborName, e.Bytes()) - copy(flds[i].cborName[n:], flds[i].name) + encodeHead(e, byte(cborTypeTextString), uint64(len(f.name))) + ef.cborName = make([]byte, e.Len()+len(f.name)) + n := copy(ef.cborName, e.Bytes()) + copy(ef.cborName[n:], f.name) e.Reset() // If cborName contains a text string, then cborNameByteString contains a // string that has the byte string major type but is otherwise identical to // cborName. - flds[i].cborNameByteString = make([]byte, len(flds[i].cborName)) - copy(flds[i].cborNameByteString, flds[i].cborName) + ef.cborNameByteString = make([]byte, len(ef.cborName)) + copy(ef.cborNameByteString, ef.cborName) // Reset encoded CBOR type to byte string, preserving the "additional // information" bits: - flds[i].cborNameByteString[0] = byte(cborTypeByteString) | - getAdditionalInformation(flds[i].cborNameByteString[0]) + ef.cborNameByteString[0] = byte(cborTypeByteString) | + getAdditionalInformation(ef.cborNameByteString[0]) hasKeyAsStr = true } // Check if field can be omitted when empty - if flds[i].omitEmpty { + if f.omitEmpty { omitEmptyIdx = append(omitEmptyIdx, i) } } - putEncodeBuffer(e) - - if err != nil { - structType := &encodingStructType{err: err} - encodingStructTypeCache.Store(t, structType) - return structType, structType.err - } // Sort fields by canonical order - bytewiseFields := make(fields, len(flds)) - copy(bytewiseFields, flds) + bytewiseFields := make(encodingFields, len(encFlds)) + copy(bytewiseFields, encFlds) sort.Sort(&bytewiseFieldSorter{bytewiseFields}) lengthFirstFields := bytewiseFields if hasKeyAsInt && hasKeyAsStr { - lengthFirstFields = make(fields, len(flds)) - copy(lengthFirstFields, flds) + lengthFirstFields = make(encodingFields, len(encFlds)) + copy(lengthFirstFields, encFlds) sort.Sort(&lengthFirstFieldSorter{lengthFirstFields}) } structType := &encodingStructType{ - fields: flds, + fields: encFlds, bytewiseFields: bytewiseFields, lengthFirstFields: lengthFirstFields, omitEmptyFieldsIdx: omitEmptyIdx, } encodingStructTypeCache.Store(t, structType) - return structType, structType.err + return structType, nil } func getEncodingStructToArrayType(t reflect.Type, flds fields) (*encodingStructType, error) { - for i := 0; i < len(flds); i++ { - // Get field's encodeFunc - flds[i].ef, flds[i].ief, flds[i].izf = getEncodeFunc(flds[i].typ) - if flds[i].ef == nil { + encFlds := make(encodingFields, len(flds)) + for i, f := range flds { + encFlds[i] = &encodingField{field: *f} + encFlds[i].ef, encFlds[i].ief, encFlds[i].izf = getEncodeFunc(f.typ) + if encFlds[i].ef == nil { structType := &encodingStructType{err: &UnsupportedTypeError{t}} encodingStructTypeCache.Store(t, structType) - return structType, structType.err + return nil, structType.err } } structType := &encodingStructType{ - fields: flds, + fields: encFlds, toArray: true, } encodingStructTypeCache.Store(t, structType) - return structType, structType.err + return structType, nil } func getEncodeFunc(t reflect.Type) (encodeFunc, isEmptyFunc, isZeroFunc) { diff --git a/vendor/github.com/fxamacker/cbor/v2/decode.go b/vendor/github.com/fxamacker/cbor/v2/decode.go index f0bdc3b..a430ecc 100644 --- a/vendor/github.com/fxamacker/cbor/v2/decode.go +++ b/vendor/github.com/fxamacker/cbor/v2/decode.go @@ -16,7 +16,6 @@ import ( "math/big" "reflect" "strconv" - "strings" "time" "unicode/utf8" @@ -326,14 +325,14 @@ func (dmkm DupMapKeyMode) valid() bool { return dmkm >= 0 && dmkm < maxDupMapKeyMode } -// IndefLengthMode specifies whether to allow indefinite length items. +// IndefLengthMode specifies whether to allow indefinite-length items. type IndefLengthMode int const ( - // IndefLengthAllowed allows indefinite length items. + // IndefLengthAllowed allows indefinite-length items. IndefLengthAllowed IndefLengthMode = iota - // IndefLengthForbidden disallows indefinite length items. + // IndefLengthForbidden disallows indefinite-length items. IndefLengthForbidden maxIndefLengthMode @@ -378,6 +377,7 @@ const ( // - int64 if value fits // - big.Int or *big.Int (see BigIntDecMode) if value < math.MinInt64 // - return UnmarshalTypeError if value > math.MaxInt64 + // // Deprecated: IntDecConvertSigned should not be used. // Please use other options, such as IntDecConvertSignedOrError, IntDecConvertSignedOrBigInt, IntDecConvertNone. IntDecConvertSigned @@ -811,7 +811,7 @@ type DecOptions struct { // Default is 128*1024=131072 and it can be set to [16, 2147483647] MaxMapPairs int - // IndefLength specifies whether to allow indefinite length CBOR items. + // IndefLength specifies whether to allow indefinite-length CBOR items. IndefLength IndefLengthMode // TagsMd specifies whether to allow CBOR tags (major type 6). @@ -1055,7 +1055,7 @@ func (opts DecOptions) decMode() (*decMode, error) { //nolint:gocritic // ignore } if !opts.ExtraReturnErrors.valid() { - return nil, errors.New("cbor: invalid ExtraReturnErrors " + strconv.Itoa(int(opts.ExtraReturnErrors))) + return nil, errors.New("cbor: invalid ExtraReturnErrors " + strconv.Itoa(int(opts.ExtraReturnErrors))) //nolint:gosec } if opts.DefaultMapType != nil && opts.DefaultMapType.Kind() != reflect.Map { @@ -1149,8 +1149,8 @@ func (opts DecOptions) decMode() (*decMode, error) { //nolint:gocritic // ignore unrecognizedTagToAny: opts.UnrecognizedTagToAny, timeTagToAny: opts.TimeTagToAny, simpleValues: simpleValues, - nanDec: opts.NaN, - infDec: opts.Inf, + nan: opts.NaN, + inf: opts.Inf, byteStringToTime: opts.ByteStringToTime, byteStringExpectedFormat: opts.ByteStringExpectedFormat, bignumTag: opts.BignumTag, @@ -1230,8 +1230,8 @@ type decMode struct { unrecognizedTagToAny UnrecognizedTagToAnyMode timeTagToAny TimeTagToAnyMode simpleValues *SimpleValueRegistry - nanDec NaNMode - infDec InfMode + nan NaNMode + inf InfMode byteStringToTime ByteStringToTimeMode byteStringExpectedFormat ByteStringExpectedFormatMode bignumTag BignumTagMode @@ -1272,8 +1272,8 @@ func (dm *decMode) DecOptions() DecOptions { UnrecognizedTagToAny: dm.unrecognizedTagToAny, TimeTagToAny: dm.timeTagToAny, SimpleValues: simpleValues, - NaN: dm.nanDec, - Inf: dm.infDec, + NaN: dm.nan, + Inf: dm.inf, ByteStringToTime: dm.byteStringToTime, ByteStringExpectedFormat: dm.byteStringExpectedFormat, BignumTag: dm.bignumTag, @@ -1583,11 +1583,11 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin _, ai, val := d.getHead() switch ai { case additionalInformationAsFloat16: - f := float64(float16.Frombits(uint16(val)).Float32()) + f := float64(float16.Frombits(uint16(val)).Float32()) //nolint:gosec return fillFloat(t, f, v) case additionalInformationAsFloat32: - f := float64(math.Float32frombits(uint32(val))) + f := float64(math.Float32frombits(uint32(val))) //nolint:gosec return fillFloat(t, f, v) case additionalInformationAsFloat64: @@ -1595,10 +1595,10 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin return fillFloat(t, f, v) default: // ai <= 24 - if d.dm.simpleValues.rejected[SimpleValue(val)] { + if d.dm.simpleValues.rejected[SimpleValue(val)] { //nolint:gosec return &UnacceptableDataItemError{ CBORType: t.String(), - Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", + Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", //nolint:gosec } } @@ -1677,20 +1677,23 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin return d.parseToValue(v, tInfo) case cborTypeArray: - if tInfo.nonPtrKind == reflect.Slice { + switch tInfo.nonPtrKind { + case reflect.Slice: return d.parseArrayToSlice(v, tInfo) - } else if tInfo.nonPtrKind == reflect.Array { + case reflect.Array: return d.parseArrayToArray(v, tInfo) - } else if tInfo.nonPtrKind == reflect.Struct { + case reflect.Struct: return d.parseArrayToStruct(v, tInfo) } + d.skip() return &UnmarshalTypeError{CBORType: t.String(), GoType: tInfo.nonPtrType.String()} case cborTypeMap: - if tInfo.nonPtrKind == reflect.Struct { + switch tInfo.nonPtrKind { + case reflect.Struct: return d.parseMapToStruct(v, tInfo) - } else if tInfo.nonPtrKind == reflect.Map { + case reflect.Map: return d.parseMapToMap(v, tInfo) } d.skip() @@ -1745,8 +1748,8 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { // Read tag number _, _, tagNum := d.getHead() if tagNum != 0 && tagNum != 1 { - d.skip() // skip tag content - return time.Time{}, false, errors.New("cbor: wrong tag number for time.Time, got " + strconv.Itoa(int(tagNum)) + ", expect 0 or 1") + d.skip() // skip tag content + return time.Time{}, false, errors.New("cbor: wrong tag number for time.Time, got " + strconv.Itoa(int(tagNum)) + ", expect 0 or 1") //nolint:gosec } } } else { @@ -1766,6 +1769,7 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { } return t, true, nil } + d.skip() return time.Time{}, false, &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String()} case cborTypeTextString: @@ -1815,10 +1819,10 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { var f float64 switch ai { case additionalInformationAsFloat16: - f = float64(float16.Frombits(uint16(val)).Float32()) + f = float64(float16.Frombits(uint16(val)).Float32()) //nolint:gosec case additionalInformationAsFloat32: - f = float64(math.Float32frombits(uint32(val))) + f = float64(math.Float32frombits(uint32(val))) //nolint:gosec case additionalInformationAsFloat64: f = math.Float64frombits(val) @@ -1832,9 +1836,17 @@ func (d *decoder) parseToTime() (time.Time, bool, error) { return time.Time{}, true, nil } seconds, fractional := math.Modf(f) + if seconds > math.MaxInt64 || seconds < math.MinInt64 { + return time.Time{}, false, &UnmarshalTypeError{ + CBORType: t.String(), + GoType: typeTime.String(), + errorMsg: fmt.Sprintf("%v overflows Go's int64", f), + } + } return time.Unix(int64(seconds), int64(fractional*1e9)), true, nil default: + d.skip() return time.Time{}, false, &UnmarshalTypeError{CBORType: t.String(), GoType: typeTime.String()} } } @@ -2145,14 +2157,14 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (any, error) { //nolint:gocyc case cborTypePrimitives: _, ai, val := d.getHead() - if ai <= 24 && d.dm.simpleValues.rejected[SimpleValue(val)] { + if ai <= 24 && d.dm.simpleValues.rejected[SimpleValue(val)] { //nolint:gosec return nil, &UnacceptableDataItemError{ CBORType: t.String(), - Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", + Message: "simple value " + strconv.FormatInt(int64(val), 10) + " is not recognized", //nolint:gosec } } if ai < 20 || ai == 24 { - return SimpleValue(val), nil + return SimpleValue(val), nil //nolint:gosec } switch ai { @@ -2165,11 +2177,11 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (any, error) { //nolint:gocyc return nil, nil case additionalInformationAsFloat16: - f := float64(float16.Frombits(uint16(val)).Float32()) + f := float64(float16.Frombits(uint16(val)).Float32()) //nolint:gosec return f, nil case additionalInformationAsFloat32: - f := float64(math.Float32frombits(uint32(val))) + f := float64(math.Float32frombits(uint32(val))) //nolint:gosec return f, nil case additionalInformationAsFloat64: @@ -2202,16 +2214,16 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (any, error) { //nolint:gocyc func (d *decoder) parseByteString() ([]byte, bool) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() if !indefiniteLength { - b := d.data[d.off : d.off+int(val)] - d.off += int(val) + b := d.data[d.off : d.off+int(val)] //nolint:gosec + d.off += int(val) //nolint:gosec return b, false } - // Process indefinite length string chunks. + // Process indefinite-length string chunks. b := []byte{} for !d.foundBreak() { _, _, val = d.getHead() - b = append(b, d.data[d.off:d.off+int(val)]...) - d.off += int(val) + b = append(b, d.data[d.off:d.off+int(val)]...) //nolint:gosec + d.off += int(val) //nolint:gosec } return b, true } @@ -2253,7 +2265,7 @@ func (d *decoder) applyByteStringTextConversion( default: // If this happens, there is a bug: the decoder has pushed an invalid // "expected later encoding" tag to the stack. - panic(fmt.Sprintf("unrecognized expected later encoding tag: %d", d.expectedLaterEncodingTags)) + panic(fmt.Sprintf("unrecognized expected later encoding tag: %d", d.expectedLaterEncodingTags[len(d.expectedLaterEncodingTags)-1])) } case reflect.Slice: @@ -2300,19 +2312,19 @@ func (d *decoder) applyByteStringTextConversion( func (d *decoder) parseTextString() ([]byte, error) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() if !indefiniteLength { - b := d.data[d.off : d.off+int(val)] - d.off += int(val) + b := d.data[d.off : d.off+int(val)] //nolint:gosec + d.off += int(val) //nolint:gosec if d.dm.utf8 == UTF8RejectInvalid && !utf8.Valid(b) { return nil, &SemanticError{"cbor: invalid UTF-8 string"} } return b, nil } - // Process indefinite length string chunks. + // Process indefinite-length string chunks. b := []byte{} for !d.foundBreak() { _, _, val = d.getHead() - x := d.data[d.off : d.off+int(val)] - d.off += int(val) + x := d.data[d.off : d.off+int(val)] //nolint:gosec + d.off += int(val) //nolint:gosec if d.dm.utf8 == UTF8RejectInvalid && !utf8.Valid(x) { for !d.foundBreak() { d.skip() // Skip remaining chunk on error @@ -2327,7 +2339,7 @@ func (d *decoder) parseTextString() ([]byte, error) { func (d *decoder) parseArray() ([]any, error) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if !hasSize { count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance } @@ -2349,7 +2361,7 @@ func (d *decoder) parseArray() ([]any, error) { func (d *decoder) parseArrayToSlice(v reflect.Value, tInfo *typeInfo) error { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if !hasSize { count = d.numOfItemsUntilBreak() // peek ahead to get array size to preallocate slice for better performance } @@ -2371,7 +2383,7 @@ func (d *decoder) parseArrayToSlice(v reflect.Value, tInfo *typeInfo) error { func (d *decoder) parseArrayToArray(v reflect.Value, tInfo *typeInfo) error { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec gi := 0 vLen := v.Len() var err error @@ -2400,7 +2412,7 @@ func (d *decoder) parseArrayToArray(v reflect.Value, tInfo *typeInfo) error { func (d *decoder) parseMap() (any, error) { _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec m := make(map[any]any) var k, e any var err, lastErr error @@ -2465,7 +2477,7 @@ func (d *decoder) parseMap() (any, error) { func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if v.IsNil() { mapsize := count if !hasSize { @@ -2566,9 +2578,9 @@ func (d *decoder) parseMapToMap(v reflect.Value, tInfo *typeInfo) error { //noli } func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { - structType := getDecodingStructType(tInfo.nonPtrType) - if structType.err != nil { - return structType.err + structType, structTypeErr := getDecodingStructType(tInfo.nonPtrType) + if structTypeErr != nil { + return structTypeErr } if !structType.toArray { @@ -2584,7 +2596,7 @@ func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { start := d.off _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec if !hasSize { count = d.numOfItemsUntilBreak() // peek ahead to get array size } @@ -2637,11 +2649,72 @@ func (d *decoder) parseArrayToStruct(v reflect.Value, tInfo *typeInfo) error { return err } -// parseMapToStruct needs to be fast so gocyclo can be ignored for now. +// skipMapEntriesFromIndex skips remaining map entries starting from index i. +func (d *decoder) skipMapEntriesFromIndex(i, count int, hasSize bool) { + for ; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { + d.skip() + d.skip() + } +} + +// skipMapForDupKey skips the current map value and all remaining map entries, +// then returns a DupMapKeyError for the given key at map index i. +func (d *decoder) skipMapForDupKey(dupKey any, i, count int, hasSize bool) error { + // Skip the value of the duplicate key. + d.skip() + // Skip all remaining map entries. + d.skipMapEntriesFromIndex(i+1, count, hasSize) + return &DupMapKeyError{dupKey, i} +} + +// skipMapForUnknownField skips the current map value and all remaining map entries, +// then returns a UnknownFieldError for the given key at map index i. +func (d *decoder) skipMapForUnknownField(i, count int, hasSize bool) error { + // Skip the value of the unknown key. + d.skip() + // Skip all remaining map entries. + d.skipMapEntriesFromIndex(i+1, count, hasSize) + return &UnknownFieldError{i} +} + +// decodeToStructField decodes the next CBOR value into the struct field f in v. +// If the field cannot be resolved, the CBOR value is skipped. +func (d *decoder) decodeToStructField(v reflect.Value, f *decodingField, tInfo *typeInfo) error { + var fv reflect.Value + + if len(f.idx) == 1 { + fv = v.Field(f.idx[0]) + } else { + var err error + fv, err = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) { + // Return a new value for embedded field null pointer to point to, or return error. + if !v.CanSet() { + return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String()) + } + v.Set(reflect.New(v.Type().Elem())) + return v, nil + }) + if !fv.IsValid() { + d.skip() + return err + } + } + + err := d.parseToValue(fv, f.typInfo) + if err != nil { + if typeError, ok := err.(*UnmarshalTypeError); ok { + typeError.StructFieldName = tInfo.nonPtrType.String() + "." + f.name + } + return err + } + + return nil +} + func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo - structType := getDecodingStructType(tInfo.nonPtrType) - if structType.err != nil { - return structType.err + structType, structTypeErr := getDecodingStructType(tInfo.nonPtrType) + if structTypeErr != nil { + return structTypeErr } if structType.toArray { @@ -2654,14 +2727,12 @@ func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //n } } - var err, lastErr error - // Get CBOR map size _, _, val, indefiniteLength := d.getHeadWithIndefiniteLengthFlag() hasSize := !indefiniteLength - count := int(val) + count := int(val) //nolint:gosec - // Keeps track of matched struct fields + // Keep track of matched struct fields to detect duplicate map keys. var foundFldIdx []bool { const maxStackFields = 128 @@ -2675,99 +2746,80 @@ func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //n } } - // Keeps track of CBOR map keys to detect duplicate map key - keyCount := 0 - var mapKeys map[any]struct{} + // Keep track of unmatched CBOR map keys to detect duplicate map keys. + var unmatchedMapKeys map[any]struct{} - errOnUnknownField := (d.dm.extraReturnErrors & ExtraDecErrorUnknownField) > 0 + var err error -MapEntryLoop: - for j := 0; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - var f *field - - // If duplicate field detection is enabled and the key at index j did not match any - // field, k will hold the map key. - var k any + caseInsensitive := d.dm.fieldNameMatching == FieldNameMatchingPreferCaseSensitive + for i := 0; (hasSize && i < count) || (!hasSize && !d.foundBreak()); i++ { t := d.nextCBORType() - if t == cborTypeTextString || (t == cborTypeByteString && d.dm.fieldNameByteString == FieldNameByteStringAllowed) { + + // Reclassify disallowed byte string keys so they fall to the default case. + // keyType is only used for branch control. + keyType := t + if t == cborTypeByteString && d.dm.fieldNameByteString != FieldNameByteStringAllowed { + keyType = 0xff + } + + switch keyType { + case cborTypeTextString, cborTypeByteString: var keyBytes []byte if t == cborTypeTextString { - keyBytes, lastErr = d.parseTextString() - if lastErr != nil { + var parseErr error + keyBytes, parseErr = d.parseTextString() + if parseErr != nil { if err == nil { - err = lastErr + err = parseErr } - d.skip() // skip value + d.skip() // Skip value continue } } else { // cborTypeByteString keyBytes, _ = d.parseByteString() } - // Check for exact match on field name. - if i, ok := structType.fieldIndicesByName[string(keyBytes)]; ok { - fld := structType.fields[i] + // Find matching struct field (exact match, then case-insensitive fallback). + if fldIdx, ok := findStructFieldByKey(structType, keyBytes, caseInsensitive); ok { + fld := structType.fields[fldIdx] - if !foundFldIdx[i] { - f = fld - foundFldIdx[i] = true - } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - err = &DupMapKeyError{fld.name, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() + switch checkDupField(d.dm, foundFldIdx, fldIdx) { + case mapActionParseValueAndContinue: + if fieldErr := d.decodeToStructField(v, fld, tInfo); fieldErr != nil && err == nil { + err = fieldErr } - return err - } else { - // discard repeated match + continue + case mapActionSkipAllAndReturnError: + return d.skipMapForDupKey(string(keyBytes), i, count, hasSize) + case mapActionSkipValueAndContinue: d.skip() - continue MapEntryLoop + continue } } - // Find field with case-insensitive match - if f == nil && d.dm.fieldNameMatching == FieldNameMatchingPreferCaseSensitive { - keyLen := len(keyBytes) - keyString := string(keyBytes) - for i := 0; i < len(structType.fields); i++ { - fld := structType.fields[i] - if len(fld.name) == keyLen && strings.EqualFold(fld.name, keyString) { - if !foundFldIdx[i] { - f = fld - foundFldIdx[i] = true - } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - err = &DupMapKeyError{keyString, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } else { - // discard repeated match - d.skip() - continue MapEntryLoop - } - break - } - } + // No matching struct field found. + if unmatchedErr := handleUnmatchedMapKey(d, string(keyBytes), i, count, hasSize, &unmatchedMapKeys); unmatchedErr != nil { + return unmatchedErr } - if d.dm.dupMapKey == DupMapKeyEnforcedAPF && f == nil { - k = string(keyBytes) - } - } else if t <= cborTypeNegativeInt { // uint/int + case cborTypePositiveInt, cborTypeNegativeInt: var nameAsInt int64 if t == cborTypePositiveInt { _, _, val := d.getHead() - nameAsInt = int64(val) + if val > math.MaxInt64 { + if err == nil { + err = &UnmarshalTypeError{ + CBORType: t.String(), + GoType: reflect.TypeOf(int64(0)).String(), + errorMsg: strconv.FormatUint(val, 10) + " overflows Go's int64", + } + } + d.skip() // skip value + continue + } + nameAsInt = int64(val) //nolint:gosec } else { _, _, val := d.getHead() if val > math.MaxInt64 { @@ -2781,39 +2833,35 @@ MapEntryLoop: d.skip() // skip value continue } - nameAsInt = int64(-1) ^ int64(val) + nameAsInt = int64(-1) ^ int64(val) //nolint:gosec } - // Find field - for i := 0; i < len(structType.fields); i++ { - fld := structType.fields[i] - if fld.keyAsInt && fld.nameAsInt == nameAsInt { - if !foundFldIdx[i] { - f = fld - foundFldIdx[i] = true - } else if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - err = &DupMapKeyError{nameAsInt, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } else { - // discard repeated match - d.skip() - continue MapEntryLoop + // Find field by integer key + if fldIdx, ok := structType.fieldIndicesByIntKey[nameAsInt]; ok { + fld := structType.fields[fldIdx] + + switch checkDupField(d.dm, foundFldIdx, fldIdx) { + case mapActionParseValueAndContinue: + if fieldErr := d.decodeToStructField(v, fld, tInfo); fieldErr != nil && err == nil { + err = fieldErr } - break + continue + case mapActionSkipAllAndReturnError: + return d.skipMapForDupKey(nameAsInt, i, count, hasSize) + case mapActionSkipValueAndContinue: + d.skip() + continue } } - if d.dm.dupMapKey == DupMapKeyEnforcedAPF && f == nil { - k = nameAsInt + // No matching struct field found. + if unmatchedErr := handleUnmatchedMapKey(d, nameAsInt, i, count, hasSize, &unmatchedMapKeys); unmatchedErr != nil { + return unmatchedErr } - } else { + + default: + // CBOR map keys that can't be matched to any struct field. + if err == nil { err = &UnmarshalTypeError{ CBORType: t.String(), @@ -2821,97 +2869,31 @@ MapEntryLoop: errorMsg: "map key is of type " + t.String() + " and cannot be used to match struct field name", } } + + var otherKey any if d.dm.dupMapKey == DupMapKeyEnforcedAPF { // parse key - k, lastErr = d.parse(true) - if lastErr != nil { + var parseErr error + otherKey, parseErr = d.parse(true) + if parseErr != nil { d.skip() // skip value continue } // Detect if CBOR map key can be used as Go map key. - if !isHashableValue(reflect.ValueOf(k)) { + if !isHashableValue(reflect.ValueOf(otherKey)) { d.skip() // skip value continue } } else { d.skip() // skip key } - } - if f == nil { - if errOnUnknownField { - err = &UnknownFieldError{j} - d.skip() // Skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } - - // Two map keys that match the same struct field are immediately considered - // duplicates. This check detects duplicates between two map keys that do - // not match a struct field. If unknown field errors are enabled, then this - // check is never reached. - if d.dm.dupMapKey == DupMapKeyEnforcedAPF { - if mapKeys == nil { - mapKeys = make(map[any]struct{}, 1) - } - mapKeys[k] = struct{}{} - newKeyCount := len(mapKeys) - if newKeyCount == keyCount { - err = &DupMapKeyError{k, j} - d.skip() // skip value - j++ - // skip the rest of the map - for ; (hasSize && j < count) || (!hasSize && !d.foundBreak()); j++ { - d.skip() - d.skip() - } - return err - } - keyCount = newKeyCount - } - - d.skip() // Skip value - continue - } - - // Get field value by index - var fv reflect.Value - if len(f.idx) == 1 { - fv = v.Field(f.idx[0]) - } else { - fv, lastErr = getFieldValue(v, f.idx, func(v reflect.Value) (reflect.Value, error) { - // Return a new value for embedded field null pointer to point to, or return error. - if !v.CanSet() { - return reflect.Value{}, errors.New("cbor: cannot set embedded pointer to unexported struct: " + v.Type().String()) - } - v.Set(reflect.New(v.Type().Elem())) - return v, nil - }) - if lastErr != nil && err == nil { - err = lastErr - } - if !fv.IsValid() { - d.skip() - continue - } - } - - if lastErr = d.parseToValue(fv, f.typInfo); lastErr != nil { - if err == nil { - if typeError, ok := lastErr.(*UnmarshalTypeError); ok { - typeError.StructFieldName = tInfo.nonPtrType.String() + "." + f.name - err = typeError - } else { - err = lastErr - } + if unmatchedErr := handleUnmatchedMapKey(d, otherKey, i, count, hasSize, &unmatchedMapKeys); unmatchedErr != nil { + return unmatchedErr } } } + return err } @@ -2958,15 +2940,15 @@ func (d *decoder) skip() { switch t { case cborTypeByteString, cborTypeTextString: - d.off += int(val) + d.off += int(val) //nolint:gosec case cborTypeArray: - for i := 0; i < int(val); i++ { + for i := 0; i < int(val); i++ { //nolint:gosec d.skip() } case cborTypeMap: - for i := 0; i < int(val)*2; i++ { + for i := 0; i < int(val)*2; i++ { //nolint:gosec d.skip() } diff --git a/vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go b/vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go new file mode 100644 index 0000000..3c8c423 --- /dev/null +++ b/vendor/github.com/fxamacker/cbor/v2/decode_map_utils.go @@ -0,0 +1,98 @@ +// Copyright (c) Faye Amacker. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +package cbor + +import "strings" + +// mapAction represents the next action during decoding a CBOR map to a Go struct. +type mapAction int + +const ( + mapActionParseValueAndContinue mapAction = iota // The caller should process the map value. + mapActionSkipValueAndContinue // The caller should skip the map value. + mapActionSkipAllAndReturnError // The caller should skip the rest of the map and return an error. +) + +// checkDupField checks if a struct field at index i has already been matched and returns the next action. +// If not matched, it marks the field as matched and returns mapActionParseValueAndContinue. +// If matched and DupMapKeyEnforcedAPF is specified in the given dm, it returns mapActionSkipAllAndReturnError. +// If matched and DupMapKeyEnforcedAPF is not specified in the given dm, it returns mapActionSkipValueAndContinue. +func checkDupField(dm *decMode, foundFldIdx []bool, i int) mapAction { + if !foundFldIdx[i] { + foundFldIdx[i] = true + return mapActionParseValueAndContinue + } + if dm.dupMapKey == DupMapKeyEnforcedAPF { + return mapActionSkipAllAndReturnError + } + return mapActionSkipValueAndContinue +} + +// findStructFieldByKey finds a struct field matching keyBytes by name. +// It tries an exact match first. If no exact match is found and +// caseInsensitive is true, it falls back to a case-insensitive search. +// findStructFieldByKey returns the field index and true, or -1 and false. +func findStructFieldByKey( + structType *decodingStructType, + keyBytes []byte, + caseInsensitive bool, +) (int, bool) { + if fldIdx, ok := structType.fieldIndicesByName[string(keyBytes)]; ok { + return fldIdx, true + } + if caseInsensitive { + return findFieldCaseInsensitive(structType.fields, string(keyBytes)) + } + return -1, false +} + +// findFieldCaseInsensitive returns the index of the first field whose name +// case-insensitively matches key, or -1 and false if no field matches. +func findFieldCaseInsensitive(flds decodingFields, key string) (int, bool) { + keyLen := len(key) + for i, f := range flds { + if f.keyAsInt { + continue + } + if len(f.name) == keyLen && strings.EqualFold(f.name, key) { + return i, true + } + } + return -1, false +} + +// handleUnmatchedMapKey handles a map entry whose key does not match any struct +// field. It can return UnknownFieldError or DupMapKeyError. +// handleUnmatchedMapKey consumes the CBOR value, so the caller doesn't need to skip any values. +// If an error is returned, the caller should abort parsing the map and return the error. +// If no error is returned, the caller should continue to process the next map pair. +func handleUnmatchedMapKey( + d *decoder, + key any, + i int, + count int, + hasSize bool, + // *map[any]struct{} is used here because we use lazy initialization for uks + uks *map[any]struct{}, //nolint:gocritic +) error { + errOnUnknownField := (d.dm.extraReturnErrors & ExtraDecErrorUnknownField) > 0 + + if errOnUnknownField { + return d.skipMapForUnknownField(i, count, hasSize) + } + + if d.dm.dupMapKey == DupMapKeyEnforcedAPF { + if *uks == nil { + *uks = make(map[any]struct{}) + } + if _, dup := (*uks)[key]; dup { + return d.skipMapForDupKey(key, i, count, hasSize) + } + (*uks)[key] = struct{}{} + } + + // Skip value. + d.skip() + return nil +} diff --git a/vendor/github.com/fxamacker/cbor/v2/diagnose.go b/vendor/github.com/fxamacker/cbor/v2/diagnose.go index 44afb86..42a67ad 100644 --- a/vendor/github.com/fxamacker/cbor/v2/diagnose.go +++ b/vendor/github.com/fxamacker/cbor/v2/diagnose.go @@ -51,11 +51,8 @@ const ( maxByteStringEncoding ) -func (bse ByteStringEncoding) valid() error { - if bse >= maxByteStringEncoding { - return errors.New("cbor: invalid ByteStringEncoding " + strconv.Itoa(int(bse))) - } - return nil +func (bse ByteStringEncoding) valid() bool { + return bse < maxByteStringEncoding } // DiagOptions specifies Diag options. @@ -104,8 +101,8 @@ func (opts DiagOptions) DiagMode() (DiagMode, error) { } func (opts DiagOptions) diagMode() (*diagMode, error) { - if err := opts.ByteStringEncoding.valid(); err != nil { - return nil, err + if !opts.ByteStringEncoding.valid() { + return nil, errors.New("cbor: invalid ByteStringEncoding " + strconv.Itoa(int(opts.ByteStringEncoding))) } decMode, err := DecOptions{ @@ -360,7 +357,7 @@ func (di *diagnose) item() error { //nolint:gocyclo case cborTypeArray: _, _, val := di.d.getHead() - count := int(val) + count := int(val) //nolint:gosec di.w.WriteByte('[') for i := 0; i < count; i++ { @@ -376,7 +373,7 @@ func (di *diagnose) item() error { //nolint:gocyclo case cborTypeMap: _, _, val := di.d.getHead() - count := int(val) + count := int(val) //nolint:gosec di.w.WriteByte('{') for i := 0; i < count; i++ { @@ -477,8 +474,8 @@ func (di *diagnose) item() error { //nolint:gocyclo func (di *diagnose) writeU16(val rune) { di.w.WriteString("\\u") var in [2]byte - in[0] = byte(val >> 8) - in[1] = byte(val) + in[0] = byte(val >> 8) //nolint:gosec + in[1] = byte(val) //nolint:gosec sz := hex.EncodedLen(len(in)) di.w.Grow(sz) dst := di.w.Bytes()[di.w.Len() : di.w.Len()+sz] @@ -608,7 +605,7 @@ func (di *diagnose) encodeTextString(val string, quote byte) error { c, size := utf8.DecodeRuneInString(val[i:]) switch { - case c == utf8.RuneError: + case c == utf8.RuneError && size == 1: return &SemanticError{"cbor: invalid UTF-8 string"} case c < utf16SurrSelf: @@ -631,7 +628,7 @@ func (di *diagnose) encodeFloat(ai byte, val uint64) error { f64 := float64(0) switch ai { case additionalInformationAsFloat16: - f16 := float16.Frombits(uint16(val)) + f16 := float16.Frombits(uint16(val)) //nolint:gosec switch { case f16.IsNaN(): di.w.WriteString("NaN") @@ -647,7 +644,7 @@ func (di *diagnose) encodeFloat(ai byte, val uint64) error { } case additionalInformationAsFloat32: - f32 := math.Float32frombits(uint32(val)) + f32 := math.Float32frombits(uint32(val)) //nolint:gosec switch { case f32 != f32: di.w.WriteString("NaN") diff --git a/vendor/github.com/fxamacker/cbor/v2/doc.go b/vendor/github.com/fxamacker/cbor/v2/doc.go index c758b73..e4c1d27 100644 --- a/vendor/github.com/fxamacker/cbor/v2/doc.go +++ b/vendor/github.com/fxamacker/cbor/v2/doc.go @@ -56,20 +56,30 @@ modes won't accidentally change at runtime after they're created. Modes are intended to be reused and are safe for concurrent use. -EncMode and DecMode Interfaces +EncMode, UserBufferEncMode, and DecMode Interfaces // EncMode interface uses immutable options and is safe for concurrent use. type EncMode interface { - Marshal(v interface{}) ([]byte, error) + Marshal(v any) ([]byte, error) NewEncoder(w io.Writer) *Encoder - EncOptions() EncOptions // returns copy of options + EncOptions() EncOptions + } + + // UserBufferEncMode extends EncMode with MarshalToBuffer, which supports + // user specified buffer rather than encoding into the built-in buffer pool. + type UserBufferEncMode interface { + EncMode + MarshalToBuffer(v any, buf *bytes.Buffer) error } // DecMode interface uses immutable options and is safe for concurrent use. type DecMode interface { - Unmarshal(data []byte, v interface{}) error + Unmarshal(data []byte, v any) error + UnmarshalFirst(data []byte, v any) (rest []byte, err error) + Valid(data []byte) error // Deprecated: use Wellformed instead. + Wellformed(data []byte) error NewDecoder(r io.Reader) *Decoder - DecOptions() DecOptions // returns copy of options + DecOptions() DecOptions } Using Default Encoding Mode diff --git a/vendor/github.com/fxamacker/cbor/v2/encode.go b/vendor/github.com/fxamacker/cbor/v2/encode.go index c550617..e65a29d 100644 --- a/vendor/github.com/fxamacker/cbor/v2/encode.go +++ b/vendor/github.com/fxamacker/cbor/v2/encode.go @@ -30,7 +30,7 @@ import ( // If value implements the Marshaler interface, Marshal calls its // MarshalCBOR method. // -// If value implements encoding.BinaryMarshaler, Marhsal calls its +// If value implements encoding.BinaryMarshaler, Marshal calls its // MarshalBinary method and encode it as CBOR byte string. // // Boolean values encode as CBOR booleans (type 7). @@ -343,7 +343,7 @@ const ( // non-UTC timezone then a "localtime - UTC" numeric offset will be included as specified in RFC3339. // NOTE: User applications can avoid including the RFC3339 numeric offset by: // - providing a time.Time value set to UTC, or - // - using the TimeUnix, TimeUnixMicro, or TimeUnixDynamic option instead of TimeRFC3339. + // - using the TimeUnix, TimeUnixMicro, TimeUnixDynamic, or TimeRFC3339NanoUTC option. TimeRFC3339 // TimeRFC3339Nano causes time.Time to encode to a CBOR time (tag 0) with a text string content @@ -351,9 +351,13 @@ const ( // non-UTC timezone then a "localtime - UTC" numeric offset will be included as specified in RFC3339. // NOTE: User applications can avoid including the RFC3339 numeric offset by: // - providing a time.Time value set to UTC, or - // - using the TimeUnix, TimeUnixMicro, or TimeUnixDynamic option instead of TimeRFC3339Nano. + // - using the TimeUnix, TimeUnixMicro, TimeUnixDynamic, or TimeRFC3339NanoUTC option. TimeRFC3339Nano + // TimeRFC3339NanoUTC causes time.Time to encode to a CBOR time (tag 0) with a text string content + // representing UTC time using nanosecond precision in RFC3339 format. + TimeRFC3339NanoUTC + maxTimeMode ) @@ -436,7 +440,7 @@ const ( // FieldNameToTextString encodes struct fields to CBOR text string (major type 3). FieldNameToTextString FieldNameMode = iota - // FieldNameToTextString encodes struct fields to CBOR byte string (major type 2). + // FieldNameToByteString encodes struct fields to CBOR byte string (major type 2). FieldNameToByteString maxFieldNameMode @@ -567,7 +571,7 @@ type EncOptions struct { // RFC3339 format gets tag number 0, and numeric epoch time tag number 1. TimeTag EncTagMode - // IndefLength specifies whether to allow indefinite length CBOR items. + // IndefLength specifies whether to allow indefinite-length CBOR items. IndefLength IndefLengthMode // NilContainers specifies how to encode nil slices and maps. @@ -1132,10 +1136,11 @@ func encodeFloat(e *bytes.Buffer, em *encMode, v reflect.Value) error { if fopt == ShortestFloat16 { var f16 float16.Float16 p := float16.PrecisionFromfloat32(f32) - if p == float16.PrecisionExact { + switch p { + case float16.PrecisionExact: // Roundtrip float32->float16->float32 test isn't needed. f16 = float16.Fromfloat32(f32) - } else if p == float16.PrecisionUnknown { + case float16.PrecisionUnknown: // Try roundtrip float32->float16->float32 to determine if float32 can fit into float16. f16 = float16.Fromfloat32(f32) if f16.Float32() == f32 { @@ -1293,10 +1298,10 @@ func encodeByteString(e *bytes.Buffer, em *encMode, v reflect.Value) error { if slen == 0 { return e.WriteByte(byte(cborTypeByteString)) } - encodeHead(e, byte(cborTypeByteString), uint64(slen)) + encodeHead(e, byte(cborTypeByteString), uint64(slen)) //nolint:gosec if vk == reflect.Array { for i := 0; i < slen; i++ { - e.WriteByte(byte(v.Index(i).Uint())) + e.WriteByte(byte(v.Index(i).Uint())) //nolint:gosec } return nil } @@ -1333,7 +1338,7 @@ func (ae arrayEncodeFunc) encode(e *bytes.Buffer, em *encMode, v reflect.Value) if alen == 0 { return e.WriteByte(byte(cborTypeArray)) } - encodeHead(e, byte(cborTypeArray), uint64(alen)) + encodeHead(e, byte(cborTypeArray), uint64(alen)) //nolint:gosec for i := 0; i < alen; i++ { if err := ae.f(e, em, v.Index(i)); err != nil { return err @@ -1364,7 +1369,7 @@ func (me mapEncodeFunc) encode(e *bytes.Buffer, em *encMode, v reflect.Value) er return e.WriteByte(byte(cborTypeMap)) } - encodeHead(e, byte(cborTypeMap), uint64(mlen)) + encodeHead(e, byte(cborTypeMap), uint64(mlen)) //nolint:gosec if em.sort == SortNone || em.sort == SortFastShuffle || mlen <= 1 { return me.e(e, em, v, nil) } @@ -1427,7 +1432,7 @@ func (x *bytewiseKeyValueSorter) Swap(i, j int) { func (x *bytewiseKeyValueSorter) Less(i, j int) bool { kvi, kvj := x.kvs[i], x.kvs[j] - return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) <= 0 + return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) < 0 } type lengthFirstKeyValueSorter struct { @@ -1448,7 +1453,7 @@ func (x *lengthFirstKeyValueSorter) Less(i, j int) bool { if keyLengthDifference := (kvi.valueOffset - kvi.offset) - (kvj.valueOffset - kvj.offset); keyLengthDifference != 0 { return keyLengthDifference < 0 } - return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) <= 0 + return bytes.Compare(x.data[kvi.offset:kvi.valueOffset], x.data[kvj.offset:kvj.valueOffset]) < 0 } var keyValuePool = sync.Pool{} @@ -1535,8 +1540,8 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { // Head is rewritten later if actual encoded field count is different from struct field count. encodedHeadLen := encodeHead(e, byte(cborTypeMap), uint64(len(flds))) - kvbegin := e.Len() - kvcount := 0 + kvBeginOffset := e.Len() + kvCount := 0 for offset := 0; offset < len(flds); offset++ { f := flds[(start+offset)%len(flds)] @@ -1582,10 +1587,10 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { return err } - kvcount++ + kvCount++ } - if len(flds) == kvcount { + if len(flds) == kvCount { // Encoded element count in head is the same as actual element count. return nil } @@ -1593,8 +1598,8 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { // Overwrite the bytes that were reserved for the head before encoding the map entries. var actualHeadLen int { - headbuf := *bytes.NewBuffer(e.Bytes()[kvbegin-encodedHeadLen : kvbegin-encodedHeadLen : kvbegin]) - actualHeadLen = encodeHead(&headbuf, byte(cborTypeMap), uint64(kvcount)) + headbuf := *bytes.NewBuffer(e.Bytes()[kvBeginOffset-encodedHeadLen : kvBeginOffset-encodedHeadLen : kvBeginOffset]) + actualHeadLen = encodeHead(&headbuf, byte(cborTypeMap), uint64(kvCount)) } if actualHeadLen == encodedHeadLen { @@ -1607,8 +1612,8 @@ func encodeStruct(e *bytes.Buffer, em *encMode, v reflect.Value) (err error) { // encoded. The encoded entries are offset to the right by the number of excess reserved // bytes. Shift the entries left to remove the gap. excessReservedBytes := encodedHeadLen - actualHeadLen - dst := e.Bytes()[kvbegin-excessReservedBytes : e.Len()-excessReservedBytes] - src := e.Bytes()[kvbegin:e.Len()] + dst := e.Bytes()[kvBeginOffset-excessReservedBytes : e.Len()-excessReservedBytes] + src := e.Bytes()[kvBeginOffset:e.Len()] copy(dst, src) // After shifting, the excess bytes are at the end of the output buffer and they are @@ -1633,7 +1638,7 @@ func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error { } if em.timeTag == EncTagRequired { tagNumber := 1 - if em.time == TimeRFC3339 || em.time == TimeRFC3339Nano { + if em.time == TimeRFC3339 || em.time == TimeRFC3339Nano || em.time == TimeRFC3339NanoUTC { tagNumber = 0 } encodeHead(e, byte(cborTypeTag), uint64(tagNumber)) @@ -1650,7 +1655,7 @@ func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error { case TimeUnixDynamic: t = t.UTC().Round(time.Microsecond) - secs, nsecs := t.Unix(), uint64(t.Nanosecond()) + secs, nsecs := t.Unix(), uint64(t.Nanosecond()) //nolint:gosec if nsecs == 0 { return encodeInt(e, em, reflect.ValueOf(secs)) } @@ -1661,6 +1666,10 @@ func encodeTime(e *bytes.Buffer, em *encMode, v reflect.Value) error { s := t.Format(time.RFC3339) return encodeString(e, em, reflect.ValueOf(s)) + case TimeRFC3339NanoUTC: + s := t.UTC().Format(time.RFC3339Nano) + return encodeString(e, em, reflect.ValueOf(s)) + default: // TimeRFC3339Nano s := t.Format(time.RFC3339Nano) return encodeString(e, em, reflect.ValueOf(s)) diff --git a/vendor/github.com/fxamacker/cbor/v2/simplevalue.go b/vendor/github.com/fxamacker/cbor/v2/simplevalue.go index 30f7281..9912e85 100644 --- a/vendor/github.com/fxamacker/cbor/v2/simplevalue.go +++ b/vendor/github.com/fxamacker/cbor/v2/simplevalue.go @@ -93,6 +93,6 @@ func (sv *SimpleValue) unmarshalCBOR(data []byte) error { // It is safe to cast val to uint8 here because // - data is already verified to be well-formed CBOR simple value and // - val is <= math.MaxUint8. - *sv = SimpleValue(val) + *sv = SimpleValue(val) //nolint:gosec return nil } diff --git a/vendor/github.com/fxamacker/cbor/v2/stream.go b/vendor/github.com/fxamacker/cbor/v2/stream.go index 7ac6d7d..282b3f7 100644 --- a/vendor/github.com/fxamacker/cbor/v2/stream.go +++ b/vendor/github.com/fxamacker/cbor/v2/stream.go @@ -6,6 +6,7 @@ package cbor import ( "bytes" "errors" + "fmt" "io" "reflect" ) @@ -157,11 +158,32 @@ func (dec *Decoder) overwriteBuf(newBuf []byte) { dec.off = 0 } +// indefDataItem tracks open indefinite-length data item during encoding. +// typ is the CBOR type of the indefinite-length data item. +// count is the number of items written so far. +// For indefinite-length maps, count must be even (key/value pairs) when +// the container is closed. +type indefDataItem struct { + typ cborType + count int +} + +// IndefiniteLengthMapOddItemCountError indicates that EndIndefinite was +// called on an open indefinite-length map with an odd number of items. +type IndefiniteLengthMapOddItemCountError struct { + count int +} + +func (e *IndefiniteLengthMapOddItemCountError) Error() string { + return fmt.Sprintf("cbor: cannot end indefinite-length map with %d item(s)", e.count) +} + // Encoder writes CBOR values to io.Writer. type Encoder struct { - w io.Writer - em *encMode - indefTypes []cborType + w io.Writer + em *encMode + indefs []indefDataItem + scratch [1]byte // reused for single-byte writes (indefinite-length head and break code) } // NewEncoder returns a new encoder that writes to w using the default encoding options. @@ -171,89 +193,166 @@ func NewEncoder(w io.Writer) *Encoder { // Encode writes the CBOR encoding of v. func (enc *Encoder) Encode(v any) error { - if len(enc.indefTypes) > 0 && v != nil { - indefType := enc.indefTypes[len(enc.indefTypes)-1] - if indefType == cborTypeTextString { - k := reflect.TypeOf(v).Kind() - if k != reflect.String { - return errors.New("cbor: cannot encode item type " + k.String() + " for indefinite-length text string") - } - } else if indefType == cborTypeByteString { - t := reflect.TypeOf(v) - k := t.Kind() - if (k != reflect.Array && k != reflect.Slice) || t.Elem().Kind() != reflect.Uint8 { - return errors.New("cbor: cannot encode item type " + k.String() + " for indefinite-length byte string") - } + if len(enc.indefs) > 0 { + err := validateIndefiniteLengthChunkByType(enc.indefs[len(enc.indefs)-1].typ, v) + if err != nil { + return err } } buf := getEncodeBuffer() err := encode(buf, enc.em, reflect.ValueOf(v)) + + // Validate the encoded chunk against the indefinite-length data item using a byte-based check. + // This reliably detects chunks from cbor.Marshaler, registered tags, StringToByteString, etc., + // which may produce a chunk inconsistent with the parent's major type. + // Applies only to indefinite-length byte/text string parents (RFC 8949 Section 3.2.3). + if err == nil && len(enc.indefs) > 0 { + err = validateIndefiniteLengthChunkByData(enc.indefs[len(enc.indefs)-1].typ, buf.Bytes(), v) + } + if err == nil { _, err = enc.w.Write(buf.Bytes()) } putEncodeBuffer(buf) - return err + + if err != nil { + return err + } + + if len(enc.indefs) > 0 { + enc.indefs[len(enc.indefs)-1].count++ + } + + return nil } -// StartIndefiniteByteString starts byte string encoding of indefinite length. +// StartIndefiniteByteString starts indefinite-length byte string encoding. // Subsequent calls of (*Encoder).Encode() encodes definite length byte strings // ("chunks") as one contiguous string until EndIndefinite is called. func (enc *Encoder) StartIndefiniteByteString() error { return enc.startIndefinite(cborTypeByteString) } -// StartIndefiniteTextString starts text string encoding of indefinite length. +// StartIndefiniteTextString starts indefinite-length text string encoding. // Subsequent calls of (*Encoder).Encode() encodes definite length text strings // ("chunks") as one contiguous string until EndIndefinite is called. func (enc *Encoder) StartIndefiniteTextString() error { return enc.startIndefinite(cborTypeTextString) } -// StartIndefiniteArray starts array encoding of indefinite length. +// StartIndefiniteArray starts indefinite-length array encoding. // Subsequent calls of (*Encoder).Encode() encodes elements of the array // until EndIndefinite is called. func (enc *Encoder) StartIndefiniteArray() error { return enc.startIndefinite(cborTypeArray) } -// StartIndefiniteMap starts array encoding of indefinite length. +// StartIndefiniteMap starts indefinite-length map encoding. // Subsequent calls of (*Encoder).Encode() encodes elements of the map // until EndIndefinite is called. func (enc *Encoder) StartIndefiniteMap() error { return enc.startIndefinite(cborTypeMap) } -// EndIndefinite closes last opened indefinite length value. +// EndIndefinite closes last opened indefinite-length value. +// It returns *IndefiniteLengthMapOddItemCountError without writing the +// "break" code if the open indefinite-length map has an odd number of +// items; the encoder state is unchanged so the caller can write the +// missing value and retry. func (enc *Encoder) EndIndefinite() error { - if len(enc.indefTypes) == 0 { + if len(enc.indefs) == 0 { return errors.New("cbor: cannot encode \"break\" code outside indefinite length values") } - _, err := enc.w.Write([]byte{cborBreakFlag}) - if err == nil { - enc.indefTypes = enc.indefTypes[:len(enc.indefTypes)-1] - } - return err -} -var cborIndefHeader = map[cborType][]byte{ - cborTypeByteString: {cborByteStringWithIndefiniteLengthHead}, - cborTypeTextString: {cborTextStringWithIndefiniteLengthHead}, - cborTypeArray: {cborArrayWithIndefiniteLengthHead}, - cborTypeMap: {cborMapWithIndefiniteLengthHead}, + // Verify that indefinite-length map has even number of elements + top := enc.indefs[len(enc.indefs)-1] + if top.typ == cborTypeMap && top.count%2 != 0 { + return &IndefiniteLengthMapOddItemCountError{count: top.count} + } + + // Write break code + enc.scratch[0] = cborBreakFlag + _, err := enc.w.Write(enc.scratch[:]) + if err != nil { + return err + } + + enc.indefs = enc.indefs[:len(enc.indefs)-1] + + // Increment parent container's item count because the child + // (indefinite-length data item) is fully written to the stream. + if len(enc.indefs) > 0 { + enc.indefs[len(enc.indefs)-1].count++ + } + + return nil } func (enc *Encoder) startIndefinite(typ cborType) error { if enc.em.indefLength == IndefLengthForbidden { return &IndefiniteLengthError{typ} } - _, err := enc.w.Write(cborIndefHeader[typ]) - if err == nil { - enc.indefTypes = append(enc.indefTypes, typ) + + // Verify that new indefinite-length data item is not a chunk in indefinite-length byte/text string. + if len(enc.indefs) > 0 { + parent := enc.indefs[len(enc.indefs)-1].typ + if parent == cborTypeByteString || parent == cborTypeTextString { + return errors.New("cbor: cannot encode indefinite-length " + typ.String() + + " as chunk of indefinite-length " + parent.String()) + } } - return err + + // Write indefinite-length head. + enc.scratch[0] = byte(typ) | additionalInformationAsIndefiniteLengthFlag + _, err := enc.w.Write(enc.scratch[:]) + if err != nil { + return err + } + + enc.indefs = append(enc.indefs, indefDataItem{typ: typ}) + return nil +} + +// validateIndefiniteLengthChunkByType rejects chunks based solely on their Go type. +func validateIndefiniteLengthChunkByType(indefiniteLengthCborType cborType, v any) error { + if indefiniteLengthCborType != cborTypeByteString && + indefiniteLengthCborType != cborTypeTextString { + return nil + } + if v == nil { + return errors.New("cbor: cannot encode nil for indefinite-length " + indefiniteLengthCborType.String()) + } + return nil +} + +// validateIndefiniteLengthChunkByData checks that chunk is a definite-length +// CBOR data item with a matching major type. +// No-op for indefinite-length array/map, where any data item is valid. +func validateIndefiniteLengthChunkByData(indefiniteLengthCborType cborType, chunk []byte, v any) error { + if indefiniteLengthCborType != cborTypeByteString && + indefiniteLengthCborType != cborTypeTextString { + return nil + } + + if len(chunk) == 0 { + return errors.New("cbor: cannot encode item type " + reflect.TypeOf(v).Kind().String() + + " for indefinite-length " + indefiniteLengthCborType.String()) + } + + t, ai := parseInitialByte(chunk[0]) + if t != indefiniteLengthCborType { + return errors.New("cbor: cannot encode item type " + reflect.TypeOf(v).Kind().String() + + " for indefinite-length " + indefiniteLengthCborType.String()) + } + + if ai == additionalInformationAsIndefiniteLengthFlag { + return errors.New("cbor: cannot encode indefinite-length " + indefiniteLengthCborType.String() + + " as chunk of indefinite-length " + indefiniteLengthCborType.String()) + } + return nil } // RawMessage is a raw encoded CBOR value. @@ -262,7 +361,9 @@ type RawMessage []byte // MarshalCBOR returns m or CBOR nil if m is nil. func (m RawMessage) MarshalCBOR() ([]byte, error) { if len(m) == 0 { - return cborNil, nil + b := make([]byte, len(cborNil)) + copy(b, cborNil) + return b, nil } return m, nil } diff --git a/vendor/github.com/fxamacker/cbor/v2/structfields.go b/vendor/github.com/fxamacker/cbor/v2/structfields.go index cf0a922..b2d71f2 100644 --- a/vendor/github.com/fxamacker/cbor/v2/structfields.go +++ b/vendor/github.com/fxamacker/cbor/v2/structfields.go @@ -6,28 +6,44 @@ package cbor import ( "reflect" "sort" + "strconv" "strings" ) +// field holds shared struct field metadata returned by getFields(). type field struct { - name string - nameAsInt int64 // used to decoder to match field name with CBOR int - cborName []byte - cborNameByteString []byte // major type 2 name encoding iff cborName has major type 3 - idx []int - typ reflect.Type - ef encodeFunc - ief isEmptyFunc - izf isZeroFunc - typInfo *typeInfo // used to decoder to reuse type info - tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields) - omitEmpty bool // used to skip empty field - omitZero bool // used to skip zero field - keyAsInt bool // used to encode/decode field name as int + name string + nameAsInt int64 // used to match field name with CBOR int + idx []int + typ reflect.Type // used during cache building only + keyAsInt bool // used to encode/decode field name as int + tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields) + omitEmpty bool // used to skip empty field + omitZero bool // used to skip zero field } type fields []*field +// encodingField extends field with encoding-specific data. +type encodingField struct { + field + cborName []byte + cborNameByteString []byte // major type 2 name encoding if cborName has major type 3 + ef encodeFunc + ief isEmptyFunc + izf isZeroFunc +} + +type encodingFields []*encodingField + +// decodingField extends field with decoding-specific data. +type decodingField struct { + field + typInfo *typeInfo // used by decoder to reuse type info +} + +type decodingFields []*decodingField + // indexFieldSorter sorts fields by field idx at each level, breaking ties with idx depth. type indexFieldSorter struct { fields fields @@ -48,7 +64,7 @@ func (x *indexFieldSorter) Less(i, j int) bool { return iIdx[k] < jIdx[k] } } - return len(iIdx) <= len(jIdx) + return len(iIdx) < len(jIdx) } // nameLevelAndTagFieldSorter sorts fields by field name, idx depth, and presence of tag. @@ -69,6 +85,10 @@ func (x *nameLevelAndTagFieldSorter) Less(i, j int) bool { if fi.name != fj.name { return fi.name < fj.name } + // Fields with the same name but different keyAsInt are in separate namespaces. + if fi.keyAsInt != fj.keyAsInt { + return fi.keyAsInt + } if len(fi.idx) != len(fj.idx) { return len(fi.idx) < len(fj.idx) } @@ -117,22 +137,37 @@ func getFields(t reflect.Type) (flds fields, structOptions string) { } } + // Normalize keyasint field names to their canonical integer string form. + // This ensures that "01", "+1", and "1" are treated as the same key + // during deduplication. + for _, f := range flds { + if f.keyAsInt { + nameAsInt, err := strconv.Atoi(f.name) + if err != nil { + continue // Leave invalid names for callers to report. + } + f.nameAsInt = int64(nameAsInt) + f.name = strconv.Itoa(nameAsInt) + } + } + sort.Sort(&nameLevelAndTagFieldSorter{flds}) // Keep visible fields. j := 0 // index of next unique field for i := 0; i < len(flds); { name := flds[i].name + keyAsInt := flds[i].keyAsInt if i == len(flds)-1 || // last field - name != flds[i+1].name || // field i has unique field name + name != flds[i+1].name || flds[i+1].keyAsInt != keyAsInt || // field i has unique (name, keyAsInt) len(flds[i].idx) < len(flds[i+1].idx) || // field i is at a less nested level than field i+1 (flds[i].tagged && !flds[i+1].tagged) { // field i is tagged while field i+1 is not flds[j] = flds[i] j++ } - // Skip fields with the same field name. - for i++; i < len(flds) && name == flds[i].name; i++ { //nolint:revive + // Skip fields with the same (name, keyAsInt). + for i++; i < len(flds) && name == flds[i].name && keyAsInt == flds[i].keyAsInt; i++ { //nolint:revive } } if j != len(flds) { diff --git a/vendor/github.com/fxamacker/cbor/v2/tag.go b/vendor/github.com/fxamacker/cbor/v2/tag.go index bd8b773..ee46e74 100644 --- a/vendor/github.com/fxamacker/cbor/v2/tag.go +++ b/vendor/github.com/fxamacker/cbor/v2/tag.go @@ -155,6 +155,7 @@ type TagSet interface { Add(opts TagOptions, contentType reflect.Type, num uint64, nestedNum ...uint64) error // Remove removes given tag content type from TagSet. + // Remove is a no-op if contentType is nil. Remove(contentType reflect.Type) tagProvider @@ -245,7 +246,11 @@ func (t *syncTagSet) Add(opts TagOptions, contentType reflect.Type, num uint64, } // Remove removes given tag content type from TagSet. +// Remove is a no-op if contentType is nil. func (t *syncTagSet) Remove(contentType reflect.Type) { + if contentType == nil { + return + } for contentType.Kind() == reflect.Pointer { contentType = contentType.Elem() } diff --git a/vendor/github.com/fxamacker/cbor/v2/valid.go b/vendor/github.com/fxamacker/cbor/v2/valid.go index b40793b..850b950 100644 --- a/vendor/github.com/fxamacker/cbor/v2/valid.go +++ b/vendor/github.com/fxamacker/cbor/v2/valid.go @@ -54,7 +54,7 @@ func (e *MaxMapPairsError) Error() string { return "cbor: exceeded max number of key-value pairs " + strconv.Itoa(e.maxMapPairs) + " for CBOR map" } -// IndefiniteLengthError indicates found disallowed indefinite length items. +// IndefiniteLengthError indicates found disallowed indefinite-length items. type IndefiniteLengthError struct { t cborType } @@ -113,7 +113,7 @@ func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, err } return d.wellformedIndefiniteString(t, depth, checkBuiltinTags) } - valInt := int(val) + valInt := int(val) //nolint:gosec if valInt < 0 { // Detect integer overflow return 0, errors.New("cbor: " + t.String() + " length " + strconv.FormatUint(val, 10) + " is too large, causing integer overflow") @@ -136,7 +136,7 @@ func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, err return d.wellformedIndefiniteArrayOrMap(t, depth, checkBuiltinTags) } - valInt := int(val) + valInt := int(val) //nolint:gosec if valInt < 0 { // Detect integer overflow return 0, errors.New("cbor: " + t.String() + " length " + strconv.FormatUint(val, 10) + " is too large, it would cause integer overflow") @@ -212,7 +212,7 @@ func (d *decoder) wellformedInternal(depth int, checkBuiltinTags bool) (int, err return depth, nil } -// wellformedIndefiniteString checks indefinite length byte/text string's well-formedness and returns max depth and error. +// wellformedIndefiniteString checks indefinite-length byte/text string's well-formedness and returns max depth and error. func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltinTags bool) (int, error) { var err error for { @@ -223,7 +223,7 @@ func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltin d.off++ break } - // Peek ahead to get next type and indefinite length status. + // Peek ahead to get next type and indefinite-length status. nt, ai := parseInitialByte(d.data[d.off]) if t != nt { return 0, &SyntaxError{"cbor: wrong element type " + nt.String() + " for indefinite-length " + t.String()} @@ -238,7 +238,7 @@ func (d *decoder) wellformedIndefiniteString(t cborType, depth int, checkBuiltin return depth, nil } -// wellformedIndefiniteArrayOrMap checks indefinite length array/map's well-formedness and returns max depth and error. +// wellformedIndefiniteArrayOrMap checks indefinite-length array/map's well-formedness and returns max depth and error. func (d *decoder) wellformedIndefiniteArrayOrMap(t cborType, depth int, checkBuiltinTags bool) (int, error) { var err error maxDepth := depth @@ -326,7 +326,7 @@ func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) val = uint64(binary.BigEndian.Uint16(d.data[d.off : d.off+argumentSize])) d.off += argumentSize if t == cborTypePrimitives { - if err := d.acceptableFloat(float64(float16.Frombits(uint16(val)).Float32())); err != nil { + if err := d.acceptableFloat(float64(float16.Frombits(uint16(val)).Float32())); err != nil { //nolint:gosec return 0, 0, 0, err } } @@ -341,7 +341,7 @@ func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) val = uint64(binary.BigEndian.Uint32(d.data[d.off : d.off+argumentSize])) d.off += argumentSize if t == cborTypePrimitives { - if err := d.acceptableFloat(float64(math.Float32frombits(uint32(val)))); err != nil { + if err := d.acceptableFloat(float64(math.Float32frombits(uint32(val)))); err != nil { //nolint:gosec return 0, 0, 0, err } } @@ -379,12 +379,12 @@ func (d *decoder) wellformedHead() (t cborType, ai byte, val uint64, err error) func (d *decoder) acceptableFloat(f float64) error { switch { - case d.dm.nanDec == NaNDecodeForbidden && math.IsNaN(f): + case d.dm.nan == NaNDecodeForbidden && math.IsNaN(f): return &UnacceptableDataItemError{ CBORType: cborTypePrimitives.String(), Message: "floating-point NaN", } - case d.dm.infDec == InfDecodeForbidden && math.IsInf(f, 0): + case d.dm.inf == InfDecodeForbidden && math.IsInf(f, 0): return &UnacceptableDataItemError{ CBORType: cborTypePrimitives.String(), Message: "floating-point infinity", diff --git a/vendor/github.com/gaissmai/bart/.coderabbit.yaml b/vendor/github.com/gaissmai/bart/.coderabbit.yaml new file mode 100644 index 0000000..0832dbd --- /dev/null +++ b/vendor/github.com/gaissmai/bart/.coderabbit.yaml @@ -0,0 +1,112 @@ +language: en-US +tone_instructions: '' +early_access: true +enable_free_tier: true +reviews: + profile: chill + request_changes_workflow: false + high_level_summary: true + high_level_summary_placeholder: '@coderabbitai summary' + high_level_summary_in_walkthrough: false + auto_title_placeholder: '@coderabbitai' + auto_title_instructions: '' + review_status: true + commit_status: true + fail_commit_status: false + collapse_walkthrough: true + changed_files_summary: true + sequence_diagrams: true + estimate_code_review_effort: true + assess_linked_issues: true + related_issues: true + related_prs: true + suggested_labels: true + auto_apply_labels: false + suggested_reviewers: false + auto_assign_reviewers: false + poem: false + labeling_instructions: [] + path_filters: + - '!**/testdata/**' + path_instructions: [] + abort_on_close: true + disable_cache: false + auto_review: + enabled: true + auto_incremental_review: true + ignore_title_keywords: ['skip ci'] + labels: [] + drafts: false + base_branches: [] + ignore_usernames: [] + finishing_touches: + docstrings: + enabled: true + unit_tests: + enabled: true + pre_merge_checks: + docstrings: + mode: warning + threshold: 80 + title: + mode: warning + requirements: '' + description: + mode: warning + issue_assessment: + mode: warning + tools: + markdownlint: + enabled: true + github-checks: + enabled: true + timeout_ms: 300000 + languagetool: + enabled: true + enabled_rules: [] + disabled_rules: [] + enabled_categories: [] + disabled_categories: [] + enabled_only: false + level: default + golangci-lint: + enabled: true + config_file: .golangci.yml + yamllint: + enabled: true + gitleaks: + enabled: true + actionlint: + enabled: true +chat: + art: false + auto_reply: true + integrations: {} +knowledge_base: + opt_out: false + web_search: + enabled: true + code_guidelines: + enabled: true + filePatterns: [] + learnings: + scope: auto + issues: + scope: auto + jira: + usage: disabled + project_keys: [] + linear: + usage: disabled + team_keys: [] + pull_requests: + scope: auto + mcp: + usage: auto + disabled_servers: [] +code_generation: + docstrings: + language: en-US + path_instructions: [] + unit_tests: + path_instructions: [] diff --git a/vendor/github.com/gaissmai/bart/.gitignore b/vendor/github.com/gaissmai/bart/.gitignore index 0bcd7ad..9c67939 100644 --- a/vendor/github.com/gaissmai/bart/.gitignore +++ b/vendor/github.com/gaissmai/bart/.gitignore @@ -23,5 +23,5 @@ # ...even if they are in subdirectories !*/ -!doc/* -!testdata/* +!scripts/** +!**/testdata/** diff --git a/vendor/github.com/gaissmai/bart/.golangci.yml b/vendor/github.com/gaissmai/bart/.golangci.yml index 487db91..bb47f80 100644 --- a/vendor/github.com/gaissmai/bart/.golangci.yml +++ b/vendor/github.com/gaissmai/bart/.golangci.yml @@ -1,34 +1,63 @@ +version: '2' +run: + timeout: 5m linters: enable: - - gofmt - - gofumpt - - goimports - - govet - - gosimple - - gocyclo - - gosmopolitan - - errcheck - - staticcheck - - intrange - - ineffassign - - unused - - typecheck - - unconvert - - unparam - - misspell - decorder - errorlint + - gocyclo + - govet + - gosec + - gosmopolitan + - intrange + - misspell - predeclared - reassign - - stylecheck + - staticcheck + - unconvert + - unparam - usestdlibvars - wastedassign - - nakedret - # - # - gosec - # - dupl - # - wrapcheck + - copyloopvar + - tparallel + - gochecknoglobals + - nolintlint + - modernize + - gocritic + settings: + govet: + enable: + - shadow + gocyclo: + min-complexity: 30 + gosec: + excludes: + - G404 # deterministic RNG in tests/benchmarks only + exclusions: + generated: lax + rules: + - linters: + - gochecknoglobals + - gosec + - gocyclo + path: _test\.go + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + paths: + - third_party$ + - builtin$ + - examples$ -linters-settings: - gocyclo: - min-complexity: 30 +formatters: + enable: + - gofmt + - goimports + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/vendor/github.com/gaissmai/bart/CONTRIBUTING.md b/vendor/github.com/gaissmai/bart/CONTRIBUTING.md index 0b1c481..ee93ccd 100644 --- a/vendor/github.com/gaissmai/bart/CONTRIBUTING.md +++ b/vendor/github.com/gaissmai/bart/CONTRIBUTING.md @@ -1 +1,14 @@ -Contributions are welcome, but please open an issue for discussion before sending a pull request. +## Contributing + +Contributions are welcome! Please open an issue first to discuss substantial changes. + +### Pull Request Checklist +- Follow Go formatting and lint rules (golangci-lint passes locally). +- Run `go test ./...` before sending PRs. +- Add/adjust tests with good coverage. +- Update README when behavior or APIs change. +- Keep commits focused; prefer small, reviewable PRs. + +### Governance +- Be respectful. +- License your contributions under MIT. diff --git a/vendor/github.com/gaissmai/bart/LICENSE b/vendor/github.com/gaissmai/bart/LICENSE index 6e65745..b441593 100644 --- a/vendor/github.com/gaissmai/bart/LICENSE +++ b/vendor/github.com/gaissmai/bart/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Karl Gaissmaier +Copyright (c) 2026 Karl Gaissmaier 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/vendor/github.com/gaissmai/bart/NODETYPES.md b/vendor/github.com/gaissmai/bart/NODETYPES.md new file mode 100644 index 0000000..889c5e4 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/NODETYPES.md @@ -0,0 +1,131 @@ +# package bart + +# Node Types Comparison + + BART implements three different node types, each optimized for specific use cases: + +## Memory Footprint (64-bit systems) + +**Base Components:** +- `BitSet256`: `[4]uint64` = **32 bytes** +- `sparse.Array256[T]`: `BitSet256 + []T` = **56 bytes + n×sizeof(T)** + +**Child Reference Sizing:** +- `childRef`: 8 bytes (pointer) or 16 bytes (interface value storage) +- The actual size depends on implementation: 8B for `*node` pointers, 16B for `interface{}` values + +### BartNode[V] - Dynamic Sparse Node + ```go +type BartNode[V any] struct { + prefixes sparse.Array256[V] // 56 + n×sizeof(V) + children sparse.Array256[childRef] // 56 + m×sizeof(childRef) + } + ``` +**Memory Usage:** **112 bytes + n×sizeof(V) + m×sizeof(childRef)** + +### LiteNode - Dynamic Sparse, prefixes Bitset-Only Node + ```go +type LiteNode struct { + prefixes bitset.BitSet256 // 32 bytes (presence only) + children sparse.Array256[childRef] // 56 + m×sizeof(childRef) + pfxCount uint16 // 2 bytes + padding + } + ``` +**Memory Usage:** **96 bytes + m×sizeof(childRef)** (no value storage) + +### FastNode[V] - Fixed Array Node + ```go +type FastNode[V any] struct { + prefixes sparse.Array256[V] // 56 + n×sizeof(V) + children sparse.Array256[childRef] // 56 + m×sizeof(childRef) + childRankCache [256]uint8 // 256 + } + ``` +**Memory Usage:** **256 + 112 bytes + n×sizeof(V) + m×sizeof(childRef)** + +## Real-World Example +**Scenario:** Node with 10 prefixes, 5 children + + | Node Type | Base | *Payload | +Children | Total | **Bytes/Prefix** ¹ | + |-----------|------|----------|----------|-----------|------------------| + | LiteNode | 96 | 0 | 5×16=80 | 176 bytes | **17** | + | BartNode[int] | 112 | 10×8=80 | 5×16=80 | 272 bytes | **27** | + | FastNode[int] | 368 | 10×8=80 | 5×16=80 | 528 bytes | **53** | + +¹ Values assume childRef = 16 bytes and pointer to payload = 8 bytes + +## Extended Memory Example with Path Compression + +### Path-Compressed Child Types + +**Note:** In realistic scenarios, the value type `V` is typically a **pointer to a +payload struct** (e.g., `*RouteInfo`, `*Metadata`). +The calculations below assume `V = 8 bytes` (pointer size on 64-bit systems). +The actual payload struct referenced by the pointer is **not included** in these per-node calculations. + +**LiteNode:** +- **LeafNode**: `netip.Prefix` only = **32 bytes** (Value field unused) +- **FringeNode**: **0 bytes** payload (prefix implicit from position, Value field unused) + +**BartNode[V] / FastNode[V]:** (assuming V is a pointer = 8 bytes) +- **LeafNode[V]**: `Value (8B) + Prefix (32B)` = **40 bytes** +- **FringeNode[V]**: `Value (8B)` = **8 bytes** (prefix implicit from position) + +### Realistic Scenario: Mixed Child Types + +**Setup:** Node with 10 prefixes + 5 child nodes + 5 LeafNodes + 5 FringeNodes + +**Total prefix items:** 10 (in-node) + 5 (leaves) + 5 (fringes) = **20 prefix items** + +| Node Type | Base | Prefixes¹ | Children² | Subtotal | + Leaves³ | + Fringes⁴ | **Bytes/Prefix**⁵ | +|-----------|------|-----------|-----------|----------|-----------|------------|-------------------| +| **LiteNode** | 96 B | 0 | 15×16=240 B | 336 B | +160 B | +0 B | **16.8** | +| **BartNode[V]** | 112 B | 10×8=80 B | 15×16=240 B | 432 B | +200 B | +40 B | **21.6** | +| **FastNode[V]** | 368 B | 10×8=80 B | 15×16=240 B | 688 B | +200 B | +40 B | **34.4** | + +**Notes:** +1. Prefixes: LiteNode stores no values (0B); BartNode/FastNode store 10×8B pointers to payload structs +2. Children: 15 total (5 nodes + 5 leaves + 5 fringes), each as `interface{}` = 16 bytes +3. Leaves: LiteNode stores 5×32B LeafNode (unused Value field), BartNode/FastNode store + 5×40B LeafNode[V] (with 8B pointer each) +4. Fringes: LiteNode stores 0B (prefix implicit, unused Value field), BartNode/FastNode store + 5×8B FringeNode[V] (8B pointer) +5. Calculated as: `Subtotal / 20` (node itself only, excluding referenced child nodes and external + payload structs) + +### Memory Efficiency Insights + +**LiteNode advantages:** +- **No value storage** in LeafNode: saves 8 bytes per leaf (32B vs 40B) +- **No value storage** in FringeNode: saves 8 bytes per fringe (0B vs 8B) +- **No in-node prefix values**: saves 80 bytes for 10 prefixes vs BartNode +- **Total savings:** ~22% smaller than BartNode for typical routing tables + +**Path compression benefits:** +- **LeafNode**: Eliminates intermediate nodes for isolated prefixes +- **FringeNode**: Compresses /8, /16, /24 boundaries without node overhead +- **Reduced trie depth**: Fewer levels = fewer lookups per route + +**Important:** The actual payload structs (e.g., routing information, metadata) are stored externally and referenced by the 8-byte pointers. Their sizes are not included in the per-node calculations above, as they are shared or application-specific. + +## Lookup Performance Deep Dive + + All three node types achieve **O(1) per-level lookup performance**, but must traverse trie levels: + +### Trie Structure & Performance +- **8-bit strides per level**: Each trie level handles 8 bits of the IP address +- **IPv4 traversal**: Worst case 4 levels (32÷8), real-world typically 3 levels for /24 routes +- **IPv6 traversal**: Worst case 16 levels (128÷8), real-world typically 6 levels for /48 routes +- **Performance characteristic**: O(trie_depth) not O(number_of_routes) +- **IPv6 vs IPv4**: IPv6 inherently ~2× slower due to deeper tree structure + +### BartNode[V] & LiteNode - Optimized Level Operations +- **Precomputed lookup tables** (`lpm.LookupTbl[idx]`) eliminate search within each level +- **BitSet256 intersections** via `IntersectionTop()` for instant prefix matching +- **Rank-based indirection**: Bitset-to-slice mapping uses precomputed Rank masks +- **Pipeline-friendly**: Only 4 bitset operations (4×uint64) per level, optimized for CPU pipelining +- **No backtracking**: Traditional longest-prefix-match backtracking replaced with direct table lookups + +### FastNode[V] - Cached Child Access per Level +- **No rank recomputation per level**: Uses `childRankCache[octet]` to index sparse child storage quickly. +- **Performance advantage**: ~25% faster level traversal diff --git a/vendor/github.com/gaissmai/bart/README.md b/vendor/github.com/gaissmai/bart/README.md index ecc62eb..ab51af4 100644 --- a/vendor/github.com/gaissmai/bart/README.md +++ b/vendor/github.com/gaissmai/bart/README.md @@ -1,183 +1,279 @@ -# package bart - ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/gaissmai/bart) [![Go Reference](https://pkg.go.dev/badge/github.com/gaissmai/bart.svg)](https://pkg.go.dev/github.com/gaissmai/bart#section-documentation) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go) [![CI](https://github.com/gaissmai/bart/actions/workflows/go.yml/badge.svg)](https://github.com/gaissmai/bart/actions/workflows/go.yml) [![Coverage Status](https://coveralls.io/repos/github/gaissmai/bart/badge.svg)](https://coveralls.io/github/gaissmai/bart) -[![Go Report Card](https://goreportcard.com/badge/github.com/gaissmai/bart)](https://goreportcard.com/report/github.com/gaissmai/bart) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua) +# package bart + +The bart package provides some **Balanced Routing Tables (BART)** for +fastest IP-to-CIDR lookups and related tasks such as: + +- **ACL** determine extremely fast whether an IP address matches any of millions of CIDR rules. +- **RIB** handle very large routing tables with low memory overhead, while keeping lookups fast. +- **FIB** high-speed lookups, achieve LPM in constant-time for packet forwarding in the datapath. + +BART is designed for workloads where both speed and/or memory efficiency matter, +making it a best fit for firewalls, routers, or any system that needs large-scale +IP prefix matching. + ## Overview -`package bart` provides a Balanced-Routing-Table (BART). +BART is implemented as a multibit trie with a fixed stride of 8 bits, +using a fast mapping function derived from Donald E. Knuth’s +**Allotment Routing Table** (ART) algorithm, to map the possible prefixes +at each level into a complete binary tree. -BART is balanced in terms of memory usage and lookup time -for the longest-prefix match. +BART implements three different routing tables, each optimized for specific +use cases: +- **bart.Lite** +- **bart.Table** +- **bart.Fast** -BART is a multibit-trie with fixed stride length of 8 bits, -using the _baseIndex_ function from the ART algorithm to -build the complete-binary-tree (CBT) of prefixes for each stride. +For **bart.Table** this binary tree is represented with popcount‑compressed +sparse arrays for **level compression**. +Combined with a **novel path and fringe compression**, this design reduces +memory consumption by nearly two orders of magnitude compared to classical ART. -The CBT is implemented as a bit-vector, backtracking is just -a matter of fast cache friendly bitmask operations. +For **bart.Fast**, an additional 256 bytes per node are used to +achieve faster level traversal in the multibit trie. -The Table is implemented with popcount compressed sparse arrays -together with path compression. This reduces storage consumption -by almost two orders of magnitude in comparison to ART with -comparable or even better lookup times for longest prefix match. +**bart.Lite** is a special form of **bart.Table**, but without a payload, and therefore +has the lowest memory overhead while maintaining the same lookup times. -The algorithm is also excellent for determining whether two tables -contain overlapping IP addresses. +## Getting Started -## Example +### Example: simple ACL with bart.Lite -```golang -func ExampleTable_Contains() { - // Create a new routing table - table := new(bart.Table[struct{}]) +```go +package main - // Insert some prefixes - prefixes := []string{ - "192.168.0.0/16", // corporate - "192.168.1.0/24", // department - "2001:7c0:3100::/40", // corporate - "2001:7c0:3100:1::/64", // department - "fc00::/7", // unique local - } +import ( + "net/netip" - for _, s := range prefixes { - pfx := netip.MustParsePrefix(s) - table.Insert(pfx, struct{}{}) - } + "github.com/gaissmai/bart" +) - // Test some IP addresses for black/whitelist containment - ips := []string{ - "192.168.1.100", // must match, department - "192.168.2.1", // must match, corporate - "2001:7c0:3100:1::1", // must match, department - "2001:7c0:3100:2::1", // must match, corporate - "fc00::1", // must match, unique local - // - "172.16.0.1", // must NOT match - "2003:dead:beef::1", // must NOT match - } +var a = netip.MustParseAddr +var p = netip.MustParsePrefix - for _, s := range ips { - ip := netip.MustParseAddr(s) - fmt.Printf("%-20s is contained: %t\n", ip, table.Contains(ip)) - } +func main() { + allowList := new(bart.Lite) - // Output: - // 192.168.1.100 is contained: true - // 192.168.2.1 is contained: true - // 2001:7c0:3100:1::1 is contained: true - // 2001:7c0:3100:2::1 is contained: true - // fc00::1 is contained: true - // 172.16.0.1 is contained: false - // 2003:dead:beef::1 is contained: false + // Add allowed networks + allowList.Insert(p("192.168.0.0/16")) + allowList.Insert(p("2001:db8::/32")) + allowList.Insert(p("10.0.0.0/24")) + + // Test some IPs with Contains (longest-prefix match) + testIPs := []netip.Addr{ + a("192.168.1.100"), // allowed (matches 192.168.0.0/16) + a("2001:db8::1"), // allowed (matches 2001:db8::/32) + a("172.16.0.1"), // denied (no match) + } + + for _, ip := range testIPs { + if allowList.Contains(ip) { + fmt.Printf("✅ %s is allowed\n", ip) + } else { + fmt.Printf("❌ %s is denied\n", ip) + } + } + + // Exact-prefix checks with Get (not longest-prefix match) + exactPrefixes := []netip.Prefix{ + p("192.168.0.0/16"), // exists exactly + p("192.168.1.0/24"), // doesn't exist (would be covered by /16, but not stored exactly) + p("10.0.0.0/24"), // exists exactly + p("10.0.0.0/16"), // doesn't exist (only /24 is stored) + } + + fmt.Println("\nExact-prefix checks:") + for _, pfx := range exactPrefixes { + if allowList.Get(pfx) { + fmt.Printf("✅ Exact prefix %s exists in table\n", pfx) + } else { + fmt.Printf("❌ Exact prefix %s not found in table\n", pfx) + } + } } ``` + +## Comparison + + | Aspect | Table | Lite | Fast | + |--------|-------------|-------------|-------------| + | **Per-level Speed** | ⚡ **O(1)** | ⚡ **O(1)** | 🚀 **O(1), ~25% faster** | + | **Overall Lookup** | O(trie_depth) | O(trie_depth) | O(trie_depth) | + | **IPv4 Performance** | ~3 level traversals | ~3 level traversals | ~3 level traversals | + | **IPv6 Performance** | ~6 level traversals | ~6 level traversals | ~6 level traversals | + | **IPv6 vs IPv4** | ~2× slower | ~2× slower | ~2× slower | + | **Memory** | efficient | very efficient | less efficient | + | **Update** | very fast | best | fast | + +A more detailed description can be found in [NODETYPES.md](NODETYPES.md). + +## When to Use Each Type + +### 🎯 **bart.Table[V]** - The Balanced Choice +- **Recommended** for most routing table use cases +- Near-optimal per-level performance with excellent memory efficiency +- Very fast updates (insert/delete) +- Perfect balance for both IPv4 and IPv6 routing tables (use it for RIB) + +### 🪶 **bart.Lite** - The Minimalist +- **Specialized** for prefix-only operations, no payload +- Same per-level performance as *bart.Table[V]* but ~35% less memory +- Optimal updates (insert/delete), ~25% faster than *bart.Table[V]* +- Ideal for IPv4/IPv6 allowlists and set-based operations (use it for ACL) + +### 🚀 **bart.Fast[V]** - The Lookup Performance Champion +- **~25% faster** when memory constraints allow +- Fast updates (insert/delete), ~50% slower than *bart.Table[V]* +- Best choice for lookup-intensive applications (use it for FIB) + +## Bitset Efficiency + +The BART algorithm is based on fixed-size bit vectors and precomputed lookup tables. +Lookups are executed entirely with fast, cache-resident bitmask operations, which +modern CPUs accelerate using specialized instructions such as POPCNT, LZCNT, and TZCNT. + +For maximum performance, specify the CPU feature set when compiling. +See the [Go minimum requirements](https://go.dev/wiki/MinimumRequirements#architectures) for details. + +```bash +# On ARM64, Go auto-selects CPU instructions. +# Example for AMD64, choose v2/v3/v4 to match your CPU features. +GOAMD64=v3 go build +``` +Critical loops over these fixed-size bitsets can be unrolled for additional speed, +ensuring predictable memory access and efficient use of CPU pipelines. + +```go +func (b *BitSet256) popcnt() (cnt int) { + cnt += bits.OnesCount64(b[0]) + cnt += bits.OnesCount64(b[1]) + cnt += bits.OnesCount64(b[2]) + cnt += bits.OnesCount64(b[3]) + return +} +``` +Future Go versions with SIMD intrinsics for `uint64` vectors may unlock +additional speedups on compatible hardware. + +## Concurrency model + +There are examples demonstrating how to use bart concurrently with multiple readers and writers. +Readers can always access the table lock‑free. Writers synchronize with a mutex so that only one writer +modifies the persistent table at a time, without relying on CAS, which can be problematic with multiple +long‑running writers. + +The combination of lock-free concurrency, fast lookup and update times and low memory consumption +provides clear advantages for any routing daemon. + +But as always, it depends on the specific use case. + +See the concurrent tests for concrete examples of this pattern: +- [ExampleFast](example_fast_concurrent_test.go) +- [ExampleLite](example_lite_concurrent_test.go) +- [ExampleTable](example_table_concurrent_test.go) + + +## Additional Use Cases + +Beyond high-performance prefix matching, BART also excels at detecting overlaps +between two routing tables. +In internal benchmarks the check runs in a few nanoseconds per query with zero +heap allocations on a modern CPU. + ## API -Release v0.18 requires at least go1.23 and we use the `iter.Seq2[netip.Prefix, V]` types for iterators. -The lock-free versions of insert, update and delete are added, but still experimentell. +BART has a rich API for CRUD, lookup, comparison, iteration, +serialization and persistence. -```golang - import "github.com/gaissmai/bart" - - type Table[V any] struct { - // Has unexported fields. - } - Table is an IPv4 and IPv6 routing table with payload V. The zero value is - ready to use. +**Table** and **Fast** expose the identical API, while **Lite** deviates in +its methods from the common API when it comes to the payload, since *Lite* +has no payload. - The Table is safe for concurrent readers but not for concurrent readers - and/or writers. Either the update operations must be protected by an - external lock mechanism or the various ...Persist functions must be used - which return a modified routing table by leaving the original unchanged +```go +import "github.com/gaissmai/bart" - A Table must not be copied by value, see Table.Clone. +type Table[V any] struct { + // Has unexported fields. +} - func (t *Table[V]) Insert(pfx netip.Prefix, val V) - func (t *Table[V]) Delete(pfx netip.Prefix) - func (t *Table[V]) Update(pfx netip.Prefix, cb func(val V, ok bool) V) (newVal V) +func (t *Table[V]) Contains(netip.Addr) bool +func (t *Table[V]) Lookup(netip.Addr) (V, bool) - func (t *Table[V]) InsertPersist(pfx netip.Prefix, val V) *Table[V] - func (t *Table[V]) DeletePersist(pfx netip.Prefix) *Table[V] - func (t *Table[V]) UpdatePersist(pfx netip.Prefix, cb func(val V, ok bool) V) (pt *Table[V], newVal V) +func (t *Table[V]) LookupPrefix(netip.Prefix) (V, bool) +func (t *Table[V]) LookupPrefixLPM(netip.Prefix) (netip.Prefix, V, bool) - func (t *Table[V]) Get(pfx netip.Prefix) (val V, ok bool) - func (t *Table[V]) GetAndDelete(pfx netip.Prefix) (val V, ok bool) - func (t *Table[V]) GetAndDeletePersist(pfx netip.Prefix) (pt *Table[V], val V, ok bool) +func (t *Table[V]) Get(netip.Prefix) (V, bool) +func (t *Table[V]) Insert(netip.Prefix, V) +func (t *Table[V]) Delete(netip.Prefix) +func (t *Table[V]) Modify(netip.Prefix, cb func(V, bool) (V, bool)) - func (t *Table[V]) Union(o *Table[V]) - func (t *Table[V]) Clone() *Table[V] +func (t *Table[V]) InsertPersist(netip.Prefix, V) *Table[V] +func (t *Table[V]) DeletePersist(netip.Prefix) *Table[V] +func (t *Table[V]) ModifyPersist(netip.Prefix, cb func(V, bool) (V, bool)) *Table[V] - func (t *Table[V]) Contains(ip netip.Addr) bool - func (t *Table[V]) Lookup(ip netip.Addr) (val V, ok bool) - func (t *Table[V]) LookupPrefix(pfx netip.Prefix) (val V, ok bool) - func (t *Table[V]) LookupPrefixLPM(pfx netip.Prefix) (lpm netip.Prefix, val V, ok bool) +func (t *Table[V]) Clone() *Table[V] +func (t *Table[V]) Union(o *Table[V]) +func (t *Table[V]) UnionPersist(o *Table[V]) *Table[V] - func (t *Table[V]) OverlapsPrefix(pfx netip.Prefix) bool +func (t *Table[V]) OverlapsPrefix(netip.Prefix) bool - func (t *Table[V]) Overlaps(o *Table[V]) bool - func (t *Table[V]) Overlaps4(o *Table[V]) bool - func (t *Table[V]) Overlaps6(o *Table[V]) bool +func (t *Table[V]) Overlaps(o *Table[V]) bool +func (t *Table[V]) Overlaps4(o *Table[V]) bool +func (t *Table[V]) Overlaps6(o *Table[V]) bool - func (t *Table[V]) Subnets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] - func (t *Table[V]) Supernets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] +func (t *Table[V]) Equal(o *Table[V]) bool - func (t *Table[V]) All() iter.Seq2[netip.Prefix, V] - func (t *Table[V]) All4() iter.Seq2[netip.Prefix, V] - func (t *Table[V]) All6() iter.Seq2[netip.Prefix, V] +func (t *Table[V]) Subnets(netip.Prefix) iter.Seq2[netip.Prefix, V] +func (t *Table[V]) Supernets(netip.Prefix) iter.Seq2[netip.Prefix, V] - func (t *Table[V]) AllSorted() iter.Seq2[netip.Prefix, V] - func (t *Table[V]) AllSorted4() iter.Seq2[netip.Prefix, V] - func (t *Table[V]) AllSorted6() iter.Seq2[netip.Prefix, V] +func (t *Table[V]) All() iter.Seq2[netip.Prefix, V] +func (t *Table[V]) All4() iter.Seq2[netip.Prefix, V] +func (t *Table[V]) All6() iter.Seq2[netip.Prefix, V] - func (t *Table[V]) Size() int - func (t *Table[V]) Size4() int - func (t *Table[V]) Size6() int +func (t *Table[V]) AllSorted() iter.Seq2[netip.Prefix, V] +func (t *Table[V]) AllSorted4() iter.Seq2[netip.Prefix, V] +func (t *Table[V]) AllSorted6() iter.Seq2[netip.Prefix, V] - func (t *Table[V]) String() string - func (t *Table[V]) Fprint(w io.Writer) error - func (t *Table[V]) MarshalText() ([]byte, error) - func (t *Table[V]) MarshalJSON() ([]byte, error) +func (t *Table[V]) Size() int +func (t *Table[V]) Size4() int +func (t *Table[V]) Size6() int - func (t *Table[V]) DumpList4() []DumpListNode[V] - func (t *Table[V]) DumpList6() []DumpListNode[V] +func (t *Table[V]) Fprint(w io.Writer) error +func (t *Table[V]) MarshalText() ([]byte, error) +func (t *Table[V]) MarshalJSON() ([]byte, error) + +func (t *Table[V]) DumpList4() []DumpListNode[V] +func (t *Table[V]) DumpList6() []DumpListNode[V] ``` -## benchmarks +## Benchmarks -Please see the extensive [benchmarks](https://github.com/gaissmai/iprbench) comparing `bart` with other IP routing table implementations. +Please see the extensive [benchmarks](https://github.com/gaissmai/iprbench) +comparing `bart` with other IP routing table implementations. -Just a teaser, Contains and Lookups against the full Internet routing table with random IP address probes: +Just a teaser, `Fast.Lookup` against the Tier1 full +Internet routing table with random IP address probes: -``` +```text +$ GOAMD64=v3 go test -run=xxx -bench=FullFastM/Lookup$ -cpu=1 goos: linux goarch: amd64 pkg: github.com/gaissmai/bart -cpu: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz -BenchmarkFullMatchV4/Contains 55906228 21.39 ns/op 0 B/op 0 allocs/op -BenchmarkFullMatchV6/Contains 100000000 11.38 ns/op 0 B/op 0 allocs/op -BenchmarkFullMissV4/Contains 52927538 22.69 ns/op 0 B/op 0 allocs/op -BenchmarkFullMissV6/Contains 250386540 4.883 ns/op 0 B/op 0 allocs/op +cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics +BenchmarkFullFastMatch4/Lookup 129484557 9.274 ns/op +BenchmarkFullFastMatch6/Lookup 65185531 17.99 ns/op +BenchmarkFullFastMiss4/Lookup 92448910 12.81 ns/op +BenchmarkFullFastMiss6/Lookup 64323817 18.66 ns/op PASS -ok github.com/gaissmai/bart 11.291s - -goos: linux -goarch: amd64 -pkg: github.com/gaissmai/bart -cpu: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz -BenchmarkFullMatchV4/Lookup 53578766 21.77 ns/op 0 B/op 0 allocs/op -BenchmarkFullMatchV6/Lookup 57054618 21.07 ns/op 0 B/op 0 allocs/op -BenchmarkFullMissV4/Lookup 48289306 25.60 ns/op 0 B/op 0 allocs/op -BenchmarkFullMissV6/Lookup 142917571 8.387 ns/op 0 B/op 0 allocs/op -PASS -ok github.com/gaissmai/bart 10.455s +ok github.com/gaissmai/bart 6.647s ``` ## Compatibility Guarantees @@ -188,20 +284,20 @@ to be revisited to better support the use cases that the library solves for. These occurrences are expected to be rare in frequency and the API is already quite stable. -## CONTRIBUTION +## Contribution Please open an issue for discussion before sending a pull request. -## CREDIT +## Credit Standing on the shoulders of giants. Credits for many inspirations go to -- the clever guys at tailscale, +- the clever folks at Tailscale, - to Daniel Lemire for his inspiring blog, -- to Donald E. Knuth for the **ART** routing algorithm and -- to Yoichi Hariguchi who deciphered it for us mere mortals +- to Donald E. Knuth for the Allotment Routing Table [ART](https://github.com/hariguchi/art/tree/master/orig) algorithm and +- to Yoichi Hariguchi who [deciphered it](https://github.com/hariguchi/art/blob/master/docs/art.pdf) for us mere mortals And last but not least to the Go team who do a wonderful job! diff --git a/vendor/github.com/gaissmai/bart/SECURITY.md b/vendor/github.com/gaissmai/bart/SECURITY.md index e2074f4..64fedc0 100644 --- a/vendor/github.com/gaissmai/bart/SECURITY.md +++ b/vendor/github.com/gaissmai/bart/SECURITY.md @@ -2,4 +2,4 @@ ## Reporting a Vulnerability -You can report privately a vulnerability by email at karl.gaissmaier@uni-ulm.de (author and maintainer). +You can report vulnerabilities privately via email: . diff --git a/vendor/github.com/gaissmai/bart/allot_lookuptbl.go b/vendor/github.com/gaissmai/bart/allot_lookuptbl.go deleted file mode 100644 index 55f575a..0000000 --- a/vendor/github.com/gaissmai/bart/allot_lookuptbl.go +++ /dev/null @@ -1,542 +0,0 @@ -// Copyright (c) 2024 Karl Gaissmaier -// SPDX-License-Identifier: MIT - -package bart - -import "github.com/gaissmai/bart/internal/bitset" - -// allotLookupTbl, as precalculated bitsets, -// map the baseIndex to bitset with precomputed complete binary tree. -// -// // 1 <= idx <= 511 -// func allotRec(aTbl *bitset.BitSet, idx uint) { -// aTbl = aTbl.Set(idx) -// if idx >= 256 { -// return -// } -// allotRec(aTbl, idx<<1) -// allotRec(aTbl, idx<<1+1) -// } -// -// Only used for fast bitset intersections instead of -// range loops in table overlaps methods. -// -// Please read the ART paper ./doc/artlookup.pdf to understand the allotment algorithm. -var allotLookupTbl = [512]bitset.BitSet{ - /* idx: 0 */ {}, // idx is invalid - /* idx: 1 */ {0xfffffffffffffffe, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}, - /* idx: 2 */ {0xffff00ff0f34, 0xffffffff, 0xffffffffffffffff, 0x0, 0xffffffffffffffff, 0xffffffffffffffff}, - /* idx: 3 */ {0xffff0000ff00f0c8, 0xffffffff00000000, 0x0, 0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff}, - /* idx: 4 */ {0xff000f0310, 0xffff, 0xffffffff, 0x0, 0xffffffffffffffff}, - /* idx: 5 */ {0xff0000f00c20, 0xffff0000, 0xffffffff00000000, 0x0, 0x0, 0xffffffffffffffff}, - /* idx: 6 */ {0xff00000f003040, 0xffff00000000, 0x0, 0xffffffff, 0x0, 0x0, 0xffffffffffffffff}, - /* idx: 7 */ {0xff000000f000c080, 0xffff000000000000, 0x0, 0xffffffff00000000, 0x0, 0x0, 0x0, 0xffffffffffffffff}, - /* idx: 8 */ {0xf00030100, 0xff, 0xffff, 0x0, 0xffffffff}, - /* idx: 9 */ {0xf0000c0200, 0xff00, 0xffff0000, 0x0, 0xffffffff00000000}, - /* idx: 10 */ {0xf0000300400, 0xff0000, 0xffff00000000, 0x0, 0x0, 0xffffffff}, - /* idx: 11 */ {0xf00000c00800, 0xff000000, 0xffff000000000000, 0x0, 0x0, 0xffffffff00000000}, - /* idx: 12 */ {0xf000003001000, 0xff00000000, 0x0, 0xffff, 0x0, 0x0, 0xffffffff}, - /* idx: 13 */ {0xf000000c002000, 0xff0000000000, 0x0, 0xffff0000, 0x0, 0x0, 0xffffffff00000000}, - /* idx: 14 */ {0xf00000030004000, 0xff000000000000, 0x0, 0xffff00000000, 0x0, 0x0, 0x0, 0xffffffff}, - /* idx: 15 */ {0xf0000000c0008000, 0xff00000000000000, 0x0, 0xffff000000000000, 0x0, 0x0, 0x0, 0xffffffff00000000}, - /* idx: 16 */ {0x300010000, 0xf, 0xff, 0x0, 0xffff}, - /* idx: 17 */ {0xc00020000, 0xf0, 0xff00, 0x0, 0xffff0000}, - /* idx: 18 */ {0x3000040000, 0xf00, 0xff0000, 0x0, 0xffff00000000}, - /* idx: 19 */ {0xc000080000, 0xf000, 0xff000000, 0x0, 0xffff000000000000}, - /* idx: 20 */ {0x30000100000, 0xf0000, 0xff00000000, 0x0, 0x0, 0xffff}, - /* idx: 21 */ {0xc0000200000, 0xf00000, 0xff0000000000, 0x0, 0x0, 0xffff0000}, - /* idx: 22 */ {0x300000400000, 0xf000000, 0xff000000000000, 0x0, 0x0, 0xffff00000000}, - /* idx: 23 */ {0xc00000800000, 0xf0000000, 0xff00000000000000, 0x0, 0x0, 0xffff000000000000}, - /* idx: 24 */ {0x3000001000000, 0xf00000000, 0x0, 0xff, 0x0, 0x0, 0xffff}, - /* idx: 25 */ {0xc000002000000, 0xf000000000, 0x0, 0xff00, 0x0, 0x0, 0xffff0000}, - /* idx: 26 */ {0x30000004000000, 0xf0000000000, 0x0, 0xff0000, 0x0, 0x0, 0xffff00000000}, - /* idx: 27 */ {0xc0000008000000, 0xf00000000000, 0x0, 0xff000000, 0x0, 0x0, 0xffff000000000000}, - /* idx: 28 */ {0x300000010000000, 0xf000000000000, 0x0, 0xff00000000, 0x0, 0x0, 0x0, 0xffff}, - /* idx: 29 */ {0xc00000020000000, 0xf0000000000000, 0x0, 0xff0000000000, 0x0, 0x0, 0x0, 0xffff0000}, - /* idx: 30 */ {0x3000000040000000, 0xf00000000000000, 0x0, 0xff000000000000, 0x0, 0x0, 0x0, 0xffff00000000}, - /* idx: 31 */ {0xc000000080000000, 0xf000000000000000, 0x0, 0xff00000000000000, 0x0, 0x0, 0x0, 0xffff000000000000}, - /* idx: 32 */ {0x100000000, 0x3, 0xf, 0x0, 0xff}, - /* idx: 33 */ {0x200000000, 0xc, 0xf0, 0x0, 0xff00}, - /* idx: 34 */ {0x400000000, 0x30, 0xf00, 0x0, 0xff0000}, - /* idx: 35 */ {0x800000000, 0xc0, 0xf000, 0x0, 0xff000000}, - /* idx: 36 */ {0x1000000000, 0x300, 0xf0000, 0x0, 0xff00000000}, - /* idx: 37 */ {0x2000000000, 0xc00, 0xf00000, 0x0, 0xff0000000000}, - /* idx: 38 */ {0x4000000000, 0x3000, 0xf000000, 0x0, 0xff000000000000}, - /* idx: 39 */ {0x8000000000, 0xc000, 0xf0000000, 0x0, 0xff00000000000000}, - /* idx: 40 */ {0x10000000000, 0x30000, 0xf00000000, 0x0, 0x0, 0xff}, - /* idx: 41 */ {0x20000000000, 0xc0000, 0xf000000000, 0x0, 0x0, 0xff00}, - /* idx: 42 */ {0x40000000000, 0x300000, 0xf0000000000, 0x0, 0x0, 0xff0000}, - /* idx: 43 */ {0x80000000000, 0xc00000, 0xf00000000000, 0x0, 0x0, 0xff000000}, - /* idx: 44 */ {0x100000000000, 0x3000000, 0xf000000000000, 0x0, 0x0, 0xff00000000}, - /* idx: 45 */ {0x200000000000, 0xc000000, 0xf0000000000000, 0x0, 0x0, 0xff0000000000}, - /* idx: 46 */ {0x400000000000, 0x30000000, 0xf00000000000000, 0x0, 0x0, 0xff000000000000}, - /* idx: 47 */ {0x800000000000, 0xc0000000, 0xf000000000000000, 0x0, 0x0, 0xff00000000000000}, - /* idx: 48 */ {0x1000000000000, 0x300000000, 0x0, 0xf, 0x0, 0x0, 0xff}, - /* idx: 49 */ {0x2000000000000, 0xc00000000, 0x0, 0xf0, 0x0, 0x0, 0xff00}, - /* idx: 50 */ {0x4000000000000, 0x3000000000, 0x0, 0xf00, 0x0, 0x0, 0xff0000}, - /* idx: 51 */ {0x8000000000000, 0xc000000000, 0x0, 0xf000, 0x0, 0x0, 0xff000000}, - /* idx: 52 */ {0x10000000000000, 0x30000000000, 0x0, 0xf0000, 0x0, 0x0, 0xff00000000}, - /* idx: 53 */ {0x20000000000000, 0xc0000000000, 0x0, 0xf00000, 0x0, 0x0, 0xff0000000000}, - /* idx: 54 */ {0x40000000000000, 0x300000000000, 0x0, 0xf000000, 0x0, 0x0, 0xff000000000000}, - /* idx: 55 */ {0x80000000000000, 0xc00000000000, 0x0, 0xf0000000, 0x0, 0x0, 0xff00000000000000}, - /* idx: 56 */ {0x100000000000000, 0x3000000000000, 0x0, 0xf00000000, 0x0, 0x0, 0x0, 0xff}, - /* idx: 57 */ {0x200000000000000, 0xc000000000000, 0x0, 0xf000000000, 0x0, 0x0, 0x0, 0xff00}, - /* idx: 58 */ {0x400000000000000, 0x30000000000000, 0x0, 0xf0000000000, 0x0, 0x0, 0x0, 0xff0000}, - /* idx: 59 */ {0x800000000000000, 0xc0000000000000, 0x0, 0xf00000000000, 0x0, 0x0, 0x0, 0xff000000}, - /* idx: 60 */ {0x1000000000000000, 0x300000000000000, 0x0, 0xf000000000000, 0x0, 0x0, 0x0, 0xff00000000}, - /* idx: 61 */ {0x2000000000000000, 0xc00000000000000, 0x0, 0xf0000000000000, 0x0, 0x0, 0x0, 0xff0000000000}, - /* idx: 62 */ {0x4000000000000000, 0x3000000000000000, 0x0, 0xf00000000000000, 0x0, 0x0, 0x0, 0xff000000000000}, - /* idx: 63 */ {0x8000000000000000, 0xc000000000000000, 0x0, 0xf000000000000000, 0x0, 0x0, 0x0, 0xff00000000000000}, - /* idx: 64 */ {0x0, 0x1, 0x3, 0x0, 0xf}, - /* idx: 65 */ {0x0, 0x2, 0xc, 0x0, 0xf0}, - /* idx: 66 */ {0x0, 0x4, 0x30, 0x0, 0xf00}, - /* idx: 67 */ {0x0, 0x8, 0xc0, 0x0, 0xf000}, - /* idx: 68 */ {0x0, 0x10, 0x300, 0x0, 0xf0000}, - /* idx: 69 */ {0x0, 0x20, 0xc00, 0x0, 0xf00000}, - /* idx: 70 */ {0x0, 0x40, 0x3000, 0x0, 0xf000000}, - /* idx: 71 */ {0x0, 0x80, 0xc000, 0x0, 0xf0000000}, - /* idx: 72 */ {0x0, 0x100, 0x30000, 0x0, 0xf00000000}, - /* idx: 73 */ {0x0, 0x200, 0xc0000, 0x0, 0xf000000000}, - /* idx: 74 */ {0x0, 0x400, 0x300000, 0x0, 0xf0000000000}, - /* idx: 75 */ {0x0, 0x800, 0xc00000, 0x0, 0xf00000000000}, - /* idx: 76 */ {0x0, 0x1000, 0x3000000, 0x0, 0xf000000000000}, - /* idx: 77 */ {0x0, 0x2000, 0xc000000, 0x0, 0xf0000000000000}, - /* idx: 78 */ {0x0, 0x4000, 0x30000000, 0x0, 0xf00000000000000}, - /* idx: 79 */ {0x0, 0x8000, 0xc0000000, 0x0, 0xf000000000000000}, - /* idx: 80 */ {0x0, 0x10000, 0x300000000, 0x0, 0x0, 0xf}, - /* idx: 81 */ {0x0, 0x20000, 0xc00000000, 0x0, 0x0, 0xf0}, - /* idx: 82 */ {0x0, 0x40000, 0x3000000000, 0x0, 0x0, 0xf00}, - /* idx: 83 */ {0x0, 0x80000, 0xc000000000, 0x0, 0x0, 0xf000}, - /* idx: 84 */ {0x0, 0x100000, 0x30000000000, 0x0, 0x0, 0xf0000}, - /* idx: 85 */ {0x0, 0x200000, 0xc0000000000, 0x0, 0x0, 0xf00000}, - /* idx: 86 */ {0x0, 0x400000, 0x300000000000, 0x0, 0x0, 0xf000000}, - /* idx: 87 */ {0x0, 0x800000, 0xc00000000000, 0x0, 0x0, 0xf0000000}, - /* idx: 88 */ {0x0, 0x1000000, 0x3000000000000, 0x0, 0x0, 0xf00000000}, - /* idx: 89 */ {0x0, 0x2000000, 0xc000000000000, 0x0, 0x0, 0xf000000000}, - /* idx: 90 */ {0x0, 0x4000000, 0x30000000000000, 0x0, 0x0, 0xf0000000000}, - /* idx: 91 */ {0x0, 0x8000000, 0xc0000000000000, 0x0, 0x0, 0xf00000000000}, - /* idx: 92 */ {0x0, 0x10000000, 0x300000000000000, 0x0, 0x0, 0xf000000000000}, - /* idx: 93 */ {0x0, 0x20000000, 0xc00000000000000, 0x0, 0x0, 0xf0000000000000}, - /* idx: 94 */ {0x0, 0x40000000, 0x3000000000000000, 0x0, 0x0, 0xf00000000000000}, - /* idx: 95 */ {0x0, 0x80000000, 0xc000000000000000, 0x0, 0x0, 0xf000000000000000}, - /* idx: 96 */ {0x0, 0x100000000, 0x0, 0x3, 0x0, 0x0, 0xf}, - /* idx: 97 */ {0x0, 0x200000000, 0x0, 0xc, 0x0, 0x0, 0xf0}, - /* idx: 98 */ {0x0, 0x400000000, 0x0, 0x30, 0x0, 0x0, 0xf00}, - /* idx: 99 */ {0x0, 0x800000000, 0x0, 0xc0, 0x0, 0x0, 0xf000}, - /* idx: 100 */ {0x0, 0x1000000000, 0x0, 0x300, 0x0, 0x0, 0xf0000}, - /* idx: 101 */ {0x0, 0x2000000000, 0x0, 0xc00, 0x0, 0x0, 0xf00000}, - /* idx: 102 */ {0x0, 0x4000000000, 0x0, 0x3000, 0x0, 0x0, 0xf000000}, - /* idx: 103 */ {0x0, 0x8000000000, 0x0, 0xc000, 0x0, 0x0, 0xf0000000}, - /* idx: 104 */ {0x0, 0x10000000000, 0x0, 0x30000, 0x0, 0x0, 0xf00000000}, - /* idx: 105 */ {0x0, 0x20000000000, 0x0, 0xc0000, 0x0, 0x0, 0xf000000000}, - /* idx: 106 */ {0x0, 0x40000000000, 0x0, 0x300000, 0x0, 0x0, 0xf0000000000}, - /* idx: 107 */ {0x0, 0x80000000000, 0x0, 0xc00000, 0x0, 0x0, 0xf00000000000}, - /* idx: 108 */ {0x0, 0x100000000000, 0x0, 0x3000000, 0x0, 0x0, 0xf000000000000}, - /* idx: 109 */ {0x0, 0x200000000000, 0x0, 0xc000000, 0x0, 0x0, 0xf0000000000000}, - /* idx: 110 */ {0x0, 0x400000000000, 0x0, 0x30000000, 0x0, 0x0, 0xf00000000000000}, - /* idx: 111 */ {0x0, 0x800000000000, 0x0, 0xc0000000, 0x0, 0x0, 0xf000000000000000}, - /* idx: 112 */ {0x0, 0x1000000000000, 0x0, 0x300000000, 0x0, 0x0, 0x0, 0xf}, - /* idx: 113 */ {0x0, 0x2000000000000, 0x0, 0xc00000000, 0x0, 0x0, 0x0, 0xf0}, - /* idx: 114 */ {0x0, 0x4000000000000, 0x0, 0x3000000000, 0x0, 0x0, 0x0, 0xf00}, - /* idx: 115 */ {0x0, 0x8000000000000, 0x0, 0xc000000000, 0x0, 0x0, 0x0, 0xf000}, - /* idx: 116 */ {0x0, 0x10000000000000, 0x0, 0x30000000000, 0x0, 0x0, 0x0, 0xf0000}, - /* idx: 117 */ {0x0, 0x20000000000000, 0x0, 0xc0000000000, 0x0, 0x0, 0x0, 0xf00000}, - /* idx: 118 */ {0x0, 0x40000000000000, 0x0, 0x300000000000, 0x0, 0x0, 0x0, 0xf000000}, - /* idx: 119 */ {0x0, 0x80000000000000, 0x0, 0xc00000000000, 0x0, 0x0, 0x0, 0xf0000000}, - /* idx: 120 */ {0x0, 0x100000000000000, 0x0, 0x3000000000000, 0x0, 0x0, 0x0, 0xf00000000}, - /* idx: 121 */ {0x0, 0x200000000000000, 0x0, 0xc000000000000, 0x0, 0x0, 0x0, 0xf000000000}, - /* idx: 122 */ {0x0, 0x400000000000000, 0x0, 0x30000000000000, 0x0, 0x0, 0x0, 0xf0000000000}, - /* idx: 123 */ {0x0, 0x800000000000000, 0x0, 0xc0000000000000, 0x0, 0x0, 0x0, 0xf00000000000}, - /* idx: 124 */ {0x0, 0x1000000000000000, 0x0, 0x300000000000000, 0x0, 0x0, 0x0, 0xf000000000000}, - /* idx: 125 */ {0x0, 0x2000000000000000, 0x0, 0xc00000000000000, 0x0, 0x0, 0x0, 0xf0000000000000}, - /* idx: 126 */ {0x0, 0x4000000000000000, 0x0, 0x3000000000000000, 0x0, 0x0, 0x0, 0xf00000000000000}, - /* idx: 127 */ {0x0, 0x8000000000000000, 0x0, 0xc000000000000000, 0x0, 0x0, 0x0, 0xf000000000000000}, - /* idx: 128 */ {0x0, 0x0, 0x1, 0x0, 0x3}, - /* idx: 129 */ {0x0, 0x0, 0x2, 0x0, 0xc}, - /* idx: 130 */ {0x0, 0x0, 0x4, 0x0, 0x30}, - /* idx: 131 */ {0x0, 0x0, 0x8, 0x0, 0xc0}, - /* idx: 132 */ {0x0, 0x0, 0x10, 0x0, 0x300}, - /* idx: 133 */ {0x0, 0x0, 0x20, 0x0, 0xc00}, - /* idx: 134 */ {0x0, 0x0, 0x40, 0x0, 0x3000}, - /* idx: 135 */ {0x0, 0x0, 0x80, 0x0, 0xc000}, - /* idx: 136 */ {0x0, 0x0, 0x100, 0x0, 0x30000}, - /* idx: 137 */ {0x0, 0x0, 0x200, 0x0, 0xc0000}, - /* idx: 138 */ {0x0, 0x0, 0x400, 0x0, 0x300000}, - /* idx: 139 */ {0x0, 0x0, 0x800, 0x0, 0xc00000}, - /* idx: 140 */ {0x0, 0x0, 0x1000, 0x0, 0x3000000}, - /* idx: 141 */ {0x0, 0x0, 0x2000, 0x0, 0xc000000}, - /* idx: 142 */ {0x0, 0x0, 0x4000, 0x0, 0x30000000}, - /* idx: 143 */ {0x0, 0x0, 0x8000, 0x0, 0xc0000000}, - /* idx: 144 */ {0x0, 0x0, 0x10000, 0x0, 0x300000000}, - /* idx: 145 */ {0x0, 0x0, 0x20000, 0x0, 0xc00000000}, - /* idx: 146 */ {0x0, 0x0, 0x40000, 0x0, 0x3000000000}, - /* idx: 147 */ {0x0, 0x0, 0x80000, 0x0, 0xc000000000}, - /* idx: 148 */ {0x0, 0x0, 0x100000, 0x0, 0x30000000000}, - /* idx: 149 */ {0x0, 0x0, 0x200000, 0x0, 0xc0000000000}, - /* idx: 150 */ {0x0, 0x0, 0x400000, 0x0, 0x300000000000}, - /* idx: 151 */ {0x0, 0x0, 0x800000, 0x0, 0xc00000000000}, - /* idx: 152 */ {0x0, 0x0, 0x1000000, 0x0, 0x3000000000000}, - /* idx: 153 */ {0x0, 0x0, 0x2000000, 0x0, 0xc000000000000}, - /* idx: 154 */ {0x0, 0x0, 0x4000000, 0x0, 0x30000000000000}, - /* idx: 155 */ {0x0, 0x0, 0x8000000, 0x0, 0xc0000000000000}, - /* idx: 156 */ {0x0, 0x0, 0x10000000, 0x0, 0x300000000000000}, - /* idx: 157 */ {0x0, 0x0, 0x20000000, 0x0, 0xc00000000000000}, - /* idx: 158 */ {0x0, 0x0, 0x40000000, 0x0, 0x3000000000000000}, - /* idx: 159 */ {0x0, 0x0, 0x80000000, 0x0, 0xc000000000000000}, - /* idx: 160 */ {0x0, 0x0, 0x100000000, 0x0, 0x0, 0x3}, - /* idx: 161 */ {0x0, 0x0, 0x200000000, 0x0, 0x0, 0xc}, - /* idx: 162 */ {0x0, 0x0, 0x400000000, 0x0, 0x0, 0x30}, - /* idx: 163 */ {0x0, 0x0, 0x800000000, 0x0, 0x0, 0xc0}, - /* idx: 164 */ {0x0, 0x0, 0x1000000000, 0x0, 0x0, 0x300}, - /* idx: 165 */ {0x0, 0x0, 0x2000000000, 0x0, 0x0, 0xc00}, - /* idx: 166 */ {0x0, 0x0, 0x4000000000, 0x0, 0x0, 0x3000}, - /* idx: 167 */ {0x0, 0x0, 0x8000000000, 0x0, 0x0, 0xc000}, - /* idx: 168 */ {0x0, 0x0, 0x10000000000, 0x0, 0x0, 0x30000}, - /* idx: 169 */ {0x0, 0x0, 0x20000000000, 0x0, 0x0, 0xc0000}, - /* idx: 170 */ {0x0, 0x0, 0x40000000000, 0x0, 0x0, 0x300000}, - /* idx: 171 */ {0x0, 0x0, 0x80000000000, 0x0, 0x0, 0xc00000}, - /* idx: 172 */ {0x0, 0x0, 0x100000000000, 0x0, 0x0, 0x3000000}, - /* idx: 173 */ {0x0, 0x0, 0x200000000000, 0x0, 0x0, 0xc000000}, - /* idx: 174 */ {0x0, 0x0, 0x400000000000, 0x0, 0x0, 0x30000000}, - /* idx: 175 */ {0x0, 0x0, 0x800000000000, 0x0, 0x0, 0xc0000000}, - /* idx: 176 */ {0x0, 0x0, 0x1000000000000, 0x0, 0x0, 0x300000000}, - /* idx: 177 */ {0x0, 0x0, 0x2000000000000, 0x0, 0x0, 0xc00000000}, - /* idx: 178 */ {0x0, 0x0, 0x4000000000000, 0x0, 0x0, 0x3000000000}, - /* idx: 179 */ {0x0, 0x0, 0x8000000000000, 0x0, 0x0, 0xc000000000}, - /* idx: 180 */ {0x0, 0x0, 0x10000000000000, 0x0, 0x0, 0x30000000000}, - /* idx: 181 */ {0x0, 0x0, 0x20000000000000, 0x0, 0x0, 0xc0000000000}, - /* idx: 182 */ {0x0, 0x0, 0x40000000000000, 0x0, 0x0, 0x300000000000}, - /* idx: 183 */ {0x0, 0x0, 0x80000000000000, 0x0, 0x0, 0xc00000000000}, - /* idx: 184 */ {0x0, 0x0, 0x100000000000000, 0x0, 0x0, 0x3000000000000}, - /* idx: 185 */ {0x0, 0x0, 0x200000000000000, 0x0, 0x0, 0xc000000000000}, - /* idx: 186 */ {0x0, 0x0, 0x400000000000000, 0x0, 0x0, 0x30000000000000}, - /* idx: 187 */ {0x0, 0x0, 0x800000000000000, 0x0, 0x0, 0xc0000000000000}, - /* idx: 188 */ {0x0, 0x0, 0x1000000000000000, 0x0, 0x0, 0x300000000000000}, - /* idx: 189 */ {0x0, 0x0, 0x2000000000000000, 0x0, 0x0, 0xc00000000000000}, - /* idx: 190 */ {0x0, 0x0, 0x4000000000000000, 0x0, 0x0, 0x3000000000000000}, - /* idx: 191 */ {0x0, 0x0, 0x8000000000000000, 0x0, 0x0, 0xc000000000000000}, - /* idx: 192 */ {0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x3}, - /* idx: 193 */ {0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0xc}, - /* idx: 194 */ {0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x30}, - /* idx: 195 */ {0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0xc0}, - /* idx: 196 */ {0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x300}, - /* idx: 197 */ {0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0xc00}, - /* idx: 198 */ {0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x3000}, - /* idx: 199 */ {0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0xc000}, - /* idx: 200 */ {0x0, 0x0, 0x0, 0x100, 0x0, 0x0, 0x30000}, - /* idx: 201 */ {0x0, 0x0, 0x0, 0x200, 0x0, 0x0, 0xc0000}, - /* idx: 202 */ {0x0, 0x0, 0x0, 0x400, 0x0, 0x0, 0x300000}, - /* idx: 203 */ {0x0, 0x0, 0x0, 0x800, 0x0, 0x0, 0xc00000}, - /* idx: 204 */ {0x0, 0x0, 0x0, 0x1000, 0x0, 0x0, 0x3000000}, - /* idx: 205 */ {0x0, 0x0, 0x0, 0x2000, 0x0, 0x0, 0xc000000}, - /* idx: 206 */ {0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x30000000}, - /* idx: 207 */ {0x0, 0x0, 0x0, 0x8000, 0x0, 0x0, 0xc0000000}, - /* idx: 208 */ {0x0, 0x0, 0x0, 0x10000, 0x0, 0x0, 0x300000000}, - /* idx: 209 */ {0x0, 0x0, 0x0, 0x20000, 0x0, 0x0, 0xc00000000}, - /* idx: 210 */ {0x0, 0x0, 0x0, 0x40000, 0x0, 0x0, 0x3000000000}, - /* idx: 211 */ {0x0, 0x0, 0x0, 0x80000, 0x0, 0x0, 0xc000000000}, - /* idx: 212 */ {0x0, 0x0, 0x0, 0x100000, 0x0, 0x0, 0x30000000000}, - /* idx: 213 */ {0x0, 0x0, 0x0, 0x200000, 0x0, 0x0, 0xc0000000000}, - /* idx: 214 */ {0x0, 0x0, 0x0, 0x400000, 0x0, 0x0, 0x300000000000}, - /* idx: 215 */ {0x0, 0x0, 0x0, 0x800000, 0x0, 0x0, 0xc00000000000}, - /* idx: 216 */ {0x0, 0x0, 0x0, 0x1000000, 0x0, 0x0, 0x3000000000000}, - /* idx: 217 */ {0x0, 0x0, 0x0, 0x2000000, 0x0, 0x0, 0xc000000000000}, - /* idx: 218 */ {0x0, 0x0, 0x0, 0x4000000, 0x0, 0x0, 0x30000000000000}, - /* idx: 219 */ {0x0, 0x0, 0x0, 0x8000000, 0x0, 0x0, 0xc0000000000000}, - /* idx: 220 */ {0x0, 0x0, 0x0, 0x10000000, 0x0, 0x0, 0x300000000000000}, - /* idx: 221 */ {0x0, 0x0, 0x0, 0x20000000, 0x0, 0x0, 0xc00000000000000}, - /* idx: 222 */ {0x0, 0x0, 0x0, 0x40000000, 0x0, 0x0, 0x3000000000000000}, - /* idx: 223 */ {0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0xc000000000000000}, - /* idx: 224 */ {0x0, 0x0, 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x3}, - /* idx: 225 */ {0x0, 0x0, 0x0, 0x200000000, 0x0, 0x0, 0x0, 0xc}, - /* idx: 226 */ {0x0, 0x0, 0x0, 0x400000000, 0x0, 0x0, 0x0, 0x30}, - /* idx: 227 */ {0x0, 0x0, 0x0, 0x800000000, 0x0, 0x0, 0x0, 0xc0}, - /* idx: 228 */ {0x0, 0x0, 0x0, 0x1000000000, 0x0, 0x0, 0x0, 0x300}, - /* idx: 229 */ {0x0, 0x0, 0x0, 0x2000000000, 0x0, 0x0, 0x0, 0xc00}, - /* idx: 230 */ {0x0, 0x0, 0x0, 0x4000000000, 0x0, 0x0, 0x0, 0x3000}, - /* idx: 231 */ {0x0, 0x0, 0x0, 0x8000000000, 0x0, 0x0, 0x0, 0xc000}, - /* idx: 232 */ {0x0, 0x0, 0x0, 0x10000000000, 0x0, 0x0, 0x0, 0x30000}, - /* idx: 233 */ {0x0, 0x0, 0x0, 0x20000000000, 0x0, 0x0, 0x0, 0xc0000}, - /* idx: 234 */ {0x0, 0x0, 0x0, 0x40000000000, 0x0, 0x0, 0x0, 0x300000}, - /* idx: 235 */ {0x0, 0x0, 0x0, 0x80000000000, 0x0, 0x0, 0x0, 0xc00000}, - /* idx: 236 */ {0x0, 0x0, 0x0, 0x100000000000, 0x0, 0x0, 0x0, 0x3000000}, - /* idx: 237 */ {0x0, 0x0, 0x0, 0x200000000000, 0x0, 0x0, 0x0, 0xc000000}, - /* idx: 238 */ {0x0, 0x0, 0x0, 0x400000000000, 0x0, 0x0, 0x0, 0x30000000}, - /* idx: 239 */ {0x0, 0x0, 0x0, 0x800000000000, 0x0, 0x0, 0x0, 0xc0000000}, - /* idx: 240 */ {0x0, 0x0, 0x0, 0x1000000000000, 0x0, 0x0, 0x0, 0x300000000}, - /* idx: 241 */ {0x0, 0x0, 0x0, 0x2000000000000, 0x0, 0x0, 0x0, 0xc00000000}, - /* idx: 242 */ {0x0, 0x0, 0x0, 0x4000000000000, 0x0, 0x0, 0x0, 0x3000000000}, - /* idx: 243 */ {0x0, 0x0, 0x0, 0x8000000000000, 0x0, 0x0, 0x0, 0xc000000000}, - /* idx: 244 */ {0x0, 0x0, 0x0, 0x10000000000000, 0x0, 0x0, 0x0, 0x30000000000}, - /* idx: 245 */ {0x0, 0x0, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0xc0000000000}, - /* idx: 246 */ {0x0, 0x0, 0x0, 0x40000000000000, 0x0, 0x0, 0x0, 0x300000000000}, - /* idx: 247 */ {0x0, 0x0, 0x0, 0x80000000000000, 0x0, 0x0, 0x0, 0xc00000000000}, - /* idx: 248 */ {0x0, 0x0, 0x0, 0x100000000000000, 0x0, 0x0, 0x0, 0x3000000000000}, - /* idx: 249 */ {0x0, 0x0, 0x0, 0x200000000000000, 0x0, 0x0, 0x0, 0xc000000000000}, - /* idx: 250 */ {0x0, 0x0, 0x0, 0x400000000000000, 0x0, 0x0, 0x0, 0x30000000000000}, - /* idx: 251 */ {0x0, 0x0, 0x0, 0x800000000000000, 0x0, 0x0, 0x0, 0xc0000000000000}, - /* idx: 252 */ {0x0, 0x0, 0x0, 0x1000000000000000, 0x0, 0x0, 0x0, 0x300000000000000}, - /* idx: 253 */ {0x0, 0x0, 0x0, 0x2000000000000000, 0x0, 0x0, 0x0, 0xc00000000000000}, - /* idx: 254 */ {0x0, 0x0, 0x0, 0x4000000000000000, 0x0, 0x0, 0x0, 0x3000000000000000}, - /* idx: 255 */ {0x0, 0x0, 0x0, 0x8000000000000000, 0x0, 0x0, 0x0, 0xc000000000000000}, - // - // START of HOST ROUTES, pfxLen == 8 - // [:4] are all 0 and only one bit is set in [4:] - // - /* idx: 256 */ {0x0, 0x0, 0x0, 0x0, 0x1}, - /* idx: 257 */ {0x0, 0x0, 0x0, 0x0, 0x2}, - /* idx: 258 */ {0x0, 0x0, 0x0, 0x0, 0x4}, - /* idx: 259 */ {0x0, 0x0, 0x0, 0x0, 0x8}, - /* idx: 260 */ {0x0, 0x0, 0x0, 0x0, 0x10}, - /* idx: 261 */ {0x0, 0x0, 0x0, 0x0, 0x20}, - /* idx: 262 */ {0x0, 0x0, 0x0, 0x0, 0x40}, - /* idx: 263 */ {0x0, 0x0, 0x0, 0x0, 0x80}, - /* idx: 264 */ {0x0, 0x0, 0x0, 0x0, 0x100}, - /* idx: 265 */ {0x0, 0x0, 0x0, 0x0, 0x200}, - /* idx: 266 */ {0x0, 0x0, 0x0, 0x0, 0x400}, - /* idx: 267 */ {0x0, 0x0, 0x0, 0x0, 0x800}, - /* idx: 268 */ {0x0, 0x0, 0x0, 0x0, 0x1000}, - /* idx: 269 */ {0x0, 0x0, 0x0, 0x0, 0x2000}, - /* idx: 270 */ {0x0, 0x0, 0x0, 0x0, 0x4000}, - /* idx: 271 */ {0x0, 0x0, 0x0, 0x0, 0x8000}, - /* idx: 272 */ {0x0, 0x0, 0x0, 0x0, 0x10000}, - /* idx: 273 */ {0x0, 0x0, 0x0, 0x0, 0x20000}, - /* idx: 274 */ {0x0, 0x0, 0x0, 0x0, 0x40000}, - /* idx: 275 */ {0x0, 0x0, 0x0, 0x0, 0x80000}, - /* idx: 276 */ {0x0, 0x0, 0x0, 0x0, 0x100000}, - /* idx: 277 */ {0x0, 0x0, 0x0, 0x0, 0x200000}, - /* idx: 278 */ {0x0, 0x0, 0x0, 0x0, 0x400000}, - /* idx: 279 */ {0x0, 0x0, 0x0, 0x0, 0x800000}, - /* idx: 280 */ {0x0, 0x0, 0x0, 0x0, 0x1000000}, - /* idx: 281 */ {0x0, 0x0, 0x0, 0x0, 0x2000000}, - /* idx: 282 */ {0x0, 0x0, 0x0, 0x0, 0x4000000}, - /* idx: 283 */ {0x0, 0x0, 0x0, 0x0, 0x8000000}, - /* idx: 284 */ {0x0, 0x0, 0x0, 0x0, 0x10000000}, - /* idx: 285 */ {0x0, 0x0, 0x0, 0x0, 0x20000000}, - /* idx: 286 */ {0x0, 0x0, 0x0, 0x0, 0x40000000}, - /* idx: 287 */ {0x0, 0x0, 0x0, 0x0, 0x80000000}, - /* idx: 288 */ {0x0, 0x0, 0x0, 0x0, 0x100000000}, - /* idx: 289 */ {0x0, 0x0, 0x0, 0x0, 0x200000000}, - /* idx: 290 */ {0x0, 0x0, 0x0, 0x0, 0x400000000}, - /* idx: 291 */ {0x0, 0x0, 0x0, 0x0, 0x800000000}, - /* idx: 292 */ {0x0, 0x0, 0x0, 0x0, 0x1000000000}, - /* idx: 293 */ {0x0, 0x0, 0x0, 0x0, 0x2000000000}, - /* idx: 294 */ {0x0, 0x0, 0x0, 0x0, 0x4000000000}, - /* idx: 295 */ {0x0, 0x0, 0x0, 0x0, 0x8000000000}, - /* idx: 296 */ {0x0, 0x0, 0x0, 0x0, 0x10000000000}, - /* idx: 297 */ {0x0, 0x0, 0x0, 0x0, 0x20000000000}, - /* idx: 298 */ {0x0, 0x0, 0x0, 0x0, 0x40000000000}, - /* idx: 299 */ {0x0, 0x0, 0x0, 0x0, 0x80000000000}, - /* idx: 300 */ {0x0, 0x0, 0x0, 0x0, 0x100000000000}, - /* idx: 301 */ {0x0, 0x0, 0x0, 0x0, 0x200000000000}, - /* idx: 302 */ {0x0, 0x0, 0x0, 0x0, 0x400000000000}, - /* idx: 303 */ {0x0, 0x0, 0x0, 0x0, 0x800000000000}, - /* idx: 304 */ {0x0, 0x0, 0x0, 0x0, 0x1000000000000}, - /* idx: 305 */ {0x0, 0x0, 0x0, 0x0, 0x2000000000000}, - /* idx: 306 */ {0x0, 0x0, 0x0, 0x0, 0x4000000000000}, - /* idx: 307 */ {0x0, 0x0, 0x0, 0x0, 0x8000000000000}, - /* idx: 308 */ {0x0, 0x0, 0x0, 0x0, 0x10000000000000}, - /* idx: 309 */ {0x0, 0x0, 0x0, 0x0, 0x20000000000000}, - /* idx: 310 */ {0x0, 0x0, 0x0, 0x0, 0x40000000000000}, - /* idx: 311 */ {0x0, 0x0, 0x0, 0x0, 0x80000000000000}, - /* idx: 312 */ {0x0, 0x0, 0x0, 0x0, 0x100000000000000}, - /* idx: 313 */ {0x0, 0x0, 0x0, 0x0, 0x200000000000000}, - /* idx: 314 */ {0x0, 0x0, 0x0, 0x0, 0x400000000000000}, - /* idx: 315 */ {0x0, 0x0, 0x0, 0x0, 0x800000000000000}, - /* idx: 316 */ {0x0, 0x0, 0x0, 0x0, 0x1000000000000000}, - /* idx: 317 */ {0x0, 0x0, 0x0, 0x0, 0x2000000000000000}, - /* idx: 318 */ {0x0, 0x0, 0x0, 0x0, 0x4000000000000000}, - /* idx: 319 */ {0x0, 0x0, 0x0, 0x0, 0x8000000000000000}, - /* idx: 320 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, - /* idx: 321 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, - /* idx: 322 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4}, - /* idx: 323 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8}, - /* idx: 324 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10}, - /* idx: 325 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20}, - /* idx: 326 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40}, - /* idx: 327 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80}, - /* idx: 328 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100}, - /* idx: 329 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200}, - /* idx: 330 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400}, - /* idx: 331 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800}, - /* idx: 332 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000}, - /* idx: 333 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000}, - /* idx: 334 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000}, - /* idx: 335 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000}, - /* idx: 336 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10000}, - /* idx: 337 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20000}, - /* idx: 338 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40000}, - /* idx: 339 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80000}, - /* idx: 340 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100000}, - /* idx: 341 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200000}, - /* idx: 342 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400000}, - /* idx: 343 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800000}, - /* idx: 344 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000}, - /* idx: 345 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000}, - /* idx: 346 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000}, - /* idx: 347 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000}, - /* idx: 348 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000}, - /* idx: 349 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000}, - /* idx: 350 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000}, - /* idx: 351 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000}, - /* idx: 352 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000}, - /* idx: 353 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000}, - /* idx: 354 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000}, - /* idx: 355 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000}, - /* idx: 356 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000}, - /* idx: 357 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000}, - /* idx: 358 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000}, - /* idx: 359 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000}, - /* idx: 360 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000}, - /* idx: 361 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000}, - /* idx: 362 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000}, - /* idx: 363 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000}, - /* idx: 364 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000}, - /* idx: 365 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000}, - /* idx: 366 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000}, - /* idx: 367 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000}, - /* idx: 368 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000}, - /* idx: 369 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000}, - /* idx: 370 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000}, - /* idx: 371 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000}, - /* idx: 372 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000000}, - /* idx: 373 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000}, - /* idx: 374 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000000}, - /* idx: 375 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000000}, - /* idx: 376 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000000}, - /* idx: 377 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000000}, - /* idx: 378 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000000}, - /* idx: 379 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000000}, - /* idx: 380 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000000}, - /* idx: 381 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000}, - /* idx: 382 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000000}, - /* idx: 383 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000000}, - /* idx: 384 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, - /* idx: 385 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, - /* idx: 386 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4}, - /* idx: 387 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8}, - /* idx: 388 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10}, - /* idx: 389 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20}, - /* idx: 390 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40}, - /* idx: 391 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80}, - /* idx: 392 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100}, - /* idx: 393 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200}, - /* idx: 394 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400}, - /* idx: 395 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800}, - /* idx: 396 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000}, - /* idx: 397 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000}, - /* idx: 398 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000}, - /* idx: 399 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000}, - /* idx: 400 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000}, - /* idx: 401 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000}, - /* idx: 402 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000}, - /* idx: 403 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000}, - /* idx: 404 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000}, - /* idx: 405 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000}, - /* idx: 406 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000}, - /* idx: 407 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000}, - /* idx: 408 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000}, - /* idx: 409 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000}, - /* idx: 410 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000}, - /* idx: 411 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000}, - /* idx: 412 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000}, - /* idx: 413 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000}, - /* idx: 414 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000}, - /* idx: 415 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000}, - /* idx: 416 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000}, - /* idx: 417 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000}, - /* idx: 418 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000}, - /* idx: 419 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000}, - /* idx: 420 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000}, - /* idx: 421 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000}, - /* idx: 422 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000}, - /* idx: 423 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000}, - /* idx: 424 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000}, - /* idx: 425 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000}, - /* idx: 426 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000}, - /* idx: 427 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000}, - /* idx: 428 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000}, - /* idx: 429 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000}, - /* idx: 430 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000}, - /* idx: 431 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000}, - /* idx: 432 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000}, - /* idx: 433 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000}, - /* idx: 434 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000}, - /* idx: 435 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000}, - /* idx: 436 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000000}, - /* idx: 437 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000}, - /* idx: 438 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000000}, - /* idx: 439 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000000}, - /* idx: 440 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000000}, - /* idx: 441 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000000}, - /* idx: 442 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000000}, - /* idx: 443 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000000}, - /* idx: 444 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000000}, - /* idx: 445 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000}, - /* idx: 446 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000000}, - /* idx: 447 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000000}, - /* idx: 448 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, - /* idx: 449 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, - /* idx: 450 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4}, - /* idx: 451 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8}, - /* idx: 452 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10}, - /* idx: 453 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20}, - /* idx: 454 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40}, - /* idx: 455 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80}, - /* idx: 456 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100}, - /* idx: 457 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200}, - /* idx: 458 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400}, - /* idx: 459 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800}, - /* idx: 460 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000}, - /* idx: 461 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000}, - /* idx: 462 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000}, - /* idx: 463 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000}, - /* idx: 464 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000}, - /* idx: 465 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000}, - /* idx: 466 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000}, - /* idx: 467 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000}, - /* idx: 468 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000}, - /* idx: 469 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000}, - /* idx: 470 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000}, - /* idx: 471 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000}, - /* idx: 472 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000}, - /* idx: 473 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000}, - /* idx: 474 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000}, - /* idx: 475 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000}, - /* idx: 476 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000}, - /* idx: 477 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000}, - /* idx: 478 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000}, - /* idx: 479 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000}, - /* idx: 480 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000}, - /* idx: 481 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000}, - /* idx: 482 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000}, - /* idx: 483 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000}, - /* idx: 484 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000}, - /* idx: 485 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000}, - /* idx: 486 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000}, - /* idx: 487 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000}, - /* idx: 488 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000}, - /* idx: 489 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000}, - /* idx: 490 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000}, - /* idx: 491 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000}, - /* idx: 492 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000}, - /* idx: 493 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000}, - /* idx: 494 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000}, - /* idx: 495 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000}, - /* idx: 496 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000}, - /* idx: 497 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000}, - /* idx: 498 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000}, - /* idx: 499 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000}, - /* idx: 500 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000000}, - /* idx: 501 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000}, - /* idx: 502 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000000}, - /* idx: 503 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000000}, - /* idx: 504 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000000}, - /* idx: 505 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000000}, - /* idx: 506 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000000}, - /* idx: 507 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000000}, - /* idx: 508 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000000}, - /* idx: 509 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000}, - /* idx: 510 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000000}, - /* idx: 511 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000000}, -} diff --git a/vendor/github.com/gaissmai/bart/bart.go b/vendor/github.com/gaissmai/bart/bart.go new file mode 100644 index 0000000..f7e860a --- /dev/null +++ b/vendor/github.com/gaissmai/bart/bart.go @@ -0,0 +1,395 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package bart + +import ( + "net/netip" + "sync" + + "github.com/gaissmai/bart/internal/art" + "github.com/gaissmai/bart/internal/lpm" + "github.com/gaissmai/bart/internal/nodes" +) + +// Table represents an IPv4 and IPv6 routing table with payload V. +// +// The zero value is ready to use. +// +// A Table must not be copied by value; always pass by pointer. +// Nil pointers as receivers or arguments are forbidden and will panic. +// +// The Table is safe for concurrent reads, but concurrent reads and writes +// must be externally synchronized. Mutation via Insert/Delete requires locks, +// or alternatively, use ...Persist methods which return a modified copy +// without altering the original table (copy-on-write). +// +// Performance note: Do not pass IPv4-in-IPv6 addresses (e.g., ::ffff:192.0.2.1) +// as input. The methods do not perform automatic unmapping to avoid unnecessary +// overhead for the common case where native addresses are used. +// Users should unmap IPv4-in-IPv6 addresses to their native IPv4 form +// (e.g., 192.0.2.1) before calling these methods. +type Table[V any] struct { + // used by -copylocks checker from `go vet`. + _ [0]sync.Mutex + + // the root nodes, implemented as popcount compressed multibit tries + root4 nodes.BartNode[V] + root6 nodes.BartNode[V] + + // the number of prefixes in the routing table + size4 int + size6 int +} + +// rootNodeByVersion, root node getter for ip version. +func (t *Table[V]) rootNodeByVersion(is4 bool) *nodes.BartNode[V] { + if is4 { + return &t.root4 + } + return &t.root6 +} + +// Insert adds or updates a prefix-value pair in the routing table. +// If the prefix already exists, its value is updated; otherwise a new entry is created. +// Invalid prefixes are silently ignored. +// +// The prefix is automatically canonicalized using pfx.Masked() to ensure +// consistent behavior regardless of host bits in the input. +func (t *Table[V]) Insert(pfx netip.Prefix, val V) { + t.insert(pfx, val) +} + +// InsertPersist is similar to Insert but the receiver isn't modified. +// +// All nodes touched during insert are cloned and a new Table is returned. +// This is not a full [Table.Clone], all untouched nodes are still referenced +// from both Tables. +// +// If the payload type V contains pointers or needs deep copying, +// it must implement the Clone method to support correct cloning. +// +// Due to cloning overhead this is significantly slower than Insert, +// typically taking μsec instead of nsec. +func (t *Table[V]) InsertPersist(pfx netip.Prefix, val V) *Table[V] { + return t.insertPersist(pfx, val) +} + +// Modify applies an insert, update, or delete operation for the value +// associated with the given prefix. The supplied callback decides the +// operation: it is called with the current value (or zero if not found) +// and a boolean indicating whether the prefix exists. The callback must +// return a new value and a delete flag: del == false inserts or updates, +// del == true deletes the entry if it exists (otherwise no-op). +// +// The callback is invoked at most once per call. +// +// The operation is determined by the callback function, which is called with: +// +// val: the current value (or zero value if not found) +// found: true if the prefix currently exists, false otherwise +// +// The callback returns: +// +// val: the new value to insert or update (ignored if del == true) +// del: true to delete the entry, false to insert or update +// +// Summary of callback semantics: +// +// | cb-input | cb-return | Ops | +// ------------------------------------- -------- +// | (zero, false) | (_, true) | no-op | +// | (zero, false) | (newVal, false) | insert | +// | (oldVal, true) | (newVal, false) | update | +// | (oldVal, true) | (_, true) | delete | +// ------------------------------------- -------- +func (t *Table[V]) Modify(pfx netip.Prefix, cb func(_ V, ok bool) (_ V, del bool)) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + + delta := n.Modify(pfx, cb) + t.sizeUpdate(is4, delta) +} + +// Contains reports whether any stored prefix covers the given IP address. +// Returns false for invalid IP addresses. +// +// This performs longest-prefix matching and returns true if any prefix +// in the routing table contains the IP address, regardless of the associated value. +// +// It does not return the value nor the prefix of the matching item, +// but as a test against an allow-/deny-list it's often sufficient +// and even few nanoseconds faster than [Table.Lookup]. +func (t *Table[V]) Contains(ip netip.Addr) bool { + // speed is top priority: no explicit test for ip.IsValid + // if ip is invalid, AsSlice() returns nil, Contains returns false. + is4 := ip.Is4() + n := t.rootNodeByVersion(is4) + + for _, octet := range ip.AsSlice() { + // for contains, any lpm match is good enough, no backtracking needed + if n.PrefixCount() != 0 && n.Contains(art.OctetToIdx(octet)) { + return true + } + + // stop traversing? + if !n.Children.Test(octet) { + return false + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *nodes.BartNode[V]: + n = kid // descend down to next trie level + + case *nodes.FringeNode[V]: + // fringe is the default-route for all possible octets below + return true + + case *nodes.LeafNode[V]: + return kid.Prefix.Contains(ip) + } + } + + return false +} + +// Lookup performs a longest prefix match (LPM) lookup for the given address. +// It finds the most specific (longest) prefix in the routing table that +// contains the given address and returns its associated value. +// +// This is the fundamental operation for IP routing decisions, finding the +// best matching route for a destination address. +// +// Returns the associated value and true if a matching prefix is found. +// Returns zero value and false if no prefix contains the address. +func (t *Table[V]) Lookup(ip netip.Addr) (val V, ok bool) { + if !ip.IsValid() { + return val, ok + } + + is4 := ip.Is4() + octets := ip.AsSlice() + + n := t.rootNodeByVersion(is4) + + // stack of the traversed nodes for fast backtracking, if needed + stack := [nodes.MaxTreeDepth]*nodes.BartNode[V]{} + + // run variable, used after for loop + var depth int + var octet byte + +LOOP: + // find leaf node + for depth, octet = range octets { + depth &= nodes.DepthMask // BCE, Lookup must be fast + + // push current node on stack for fast backtracking + stack[depth] = n + + // go down in tight loop to last octet + if !n.Children.Test(octet) { + // no more nodes below octet + break LOOP + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *nodes.BartNode[V]: + n = kid + continue LOOP // descend down to next trie level + + case *nodes.FringeNode[V]: + // fringe is the default-route for all possible nodes below + return kid.Value, true + + case *nodes.LeafNode[V]: + if kid.Prefix.Contains(ip) { + return kid.Value, true + } + // reached a path compressed prefix, stop traversing + break LOOP + } + } + + // start backtracking, unwind the stack, bounds check eliminated + for ; depth >= 0; depth-- { + depth &= nodes.DepthMask // BCE + + n = stack[depth] + + // longest prefix match, skip if node has no prefixes + if n.PrefixCount() != 0 { + idx := art.OctetToIdx(octets[depth]) + // lookupIdx() manually inlined + if lpmIdx, ok2 := n.Prefixes.IntersectionTop(&lpm.LookupTbl[idx]); ok2 { + return n.MustGetPrefix(lpmIdx), ok2 + } + } + } + + return val, ok +} + +// LookupPrefix performs a longest prefix match lookup for any address within +// the given prefix. It finds the most specific routing table entry that would +// match any address in the provided prefix range. +// +// This is functionally identical to LookupPrefixLPM but returns only the +// associated value, not the matching prefix itself. +// +// Returns the value and true if a matching prefix is found. +// Returns zero value and false if no match exists. +func (t *Table[V]) LookupPrefix(pfx netip.Prefix) (val V, ok bool) { + _, val, ok = t.lookupPrefixLPM(pfx, false) + return val, ok +} + +// LookupPrefixLPM performs a longest prefix match lookup for any address within +// the given prefix. It finds the most specific routing table entry that would +// match any address in the provided prefix range. +// +// This is functionally identical to LookupPrefix but additionally returns the +// matching LPM prefix itself along with the value. +// +// This method is slower than LookupPrefix and should only be used if the +// matching lpm entry is also required for other reasons. +// +// Returns the matching prefix, its associated value, and true if found. +// Returns zero values and false if no match exists. +func (t *Table[V]) LookupPrefixLPM(pfx netip.Prefix) (lpmPfx netip.Prefix, val V, ok bool) { + return t.lookupPrefixLPM(pfx, true) +} + +func (t *Table[V]) lookupPrefixLPM(pfx netip.Prefix, withLPM bool) (lpmPfx netip.Prefix, val V, ok bool) { + if !pfx.IsValid() { + return lpmPfx, val, ok + } + + // canonicalize the prefix + pfx = pfx.Masked() + + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := nodes.DivMod8(pfxLen) + + n := t.rootNodeByVersion(is4) + + // record path to leaf node + stack := [nodes.MaxTreeDepth]*nodes.BartNode[V]{} + + var depth int + var octet byte + +LOOP: + // find the last node on the octets path in the trie, + for depth, octet = range octets { + depth &= nodes.DepthMask // BCE + + // stepped one past the last stride of interest; back up to last and break + if depth > strideCount { + depth-- + break + } + // push current node on stack + stack[depth] = n + + // go down in tight loop to leaf node + if !n.Children.Test(octet) { + break LOOP + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *nodes.BartNode[V]: + n = kid + continue LOOP // descend down to next trie level + + case *nodes.LeafNode[V]: + // reached a path compressed prefix, stop traversing + if kid.Prefix.Bits() > pfxLen || !kid.Prefix.Contains(ip) { + break LOOP + } + return kid.Prefix, kid.Value, true + + case *nodes.FringeNode[V]: + // the bits of the fringe are defined by the depth + // maybe the LPM isn't needed, saves some cycles + fringeBits := (depth + 1) << 3 + if fringeBits > pfxLen { + break LOOP + } + + // the LPM isn't needed, saves some cycles + if !withLPM { + return netip.Prefix{}, kid.Value, true + } + + // get the LPM prefix back from ip and depth + // it's a fringe, bits are always /8, /16, /24, ... + fringePfx, _ := ip.Prefix((depth + 1) << 3) + return fringePfx, kid.Value, true + } + } + + // start backtracking, unwind the stack + for ; depth >= 0; depth-- { + depth &= nodes.DepthMask // BCE + + n = stack[depth] + + // longest prefix match, skip if node has no prefixes + if n.Prefixes.Len() == 0 { + continue + } + + var idx uint8 + octet = octets[depth] + + // only the final stride may have a different prefix len + // all others are just host routes + if depth == strideCount { + idx = art.PfxToIdx(octet, modBits) + } else { + idx = art.OctetToIdx(octet) + } + + // manually inlined: lookupIdx(idx) + var topIdx uint8 + if topIdx, ok = n.Prefixes.IntersectionTop(&lpm.LookupTbl[idx]); ok { + val = n.MustGetPrefix(topIdx) + + // called from LookupPrefix + if !withLPM { + return netip.Prefix{}, val, ok + } + + // called from LookupPrefixLPM + + // get the bits from depth and top idx + pfxBits := int(art.PfxBits(depth, topIdx)) + + // calculate the lpmPfx from incoming ip and new mask + // netip.Addr.Prefix canonicalizes. Invariant: art.PfxBits(depth, topIdx) + // yields a valid mask (v4: 0..32, v6: 0..128), so error is impossible. + lpmPfx, _ = ip.Prefix(pfxBits) + return lpmPfx, val, ok + } + } + + return lpmPfx, val, ok +} diff --git a/vendor/github.com/gaissmai/bart/bartmethodsgenerated.go b/vendor/github.com/gaissmai/bart/bartmethodsgenerated.go new file mode 100644 index 0000000..a75cba6 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/bartmethodsgenerated.go @@ -0,0 +1,731 @@ +// Code generated from file "commonmethods_tmpl.go"; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package bart + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "iter" + "net/netip" + "slices" + "strings" + + "github.com/gaissmai/bart/internal/nodes" + "github.com/gaissmai/bart/internal/value" +) + +func (t *Table[V]) sizeUpdate(is4 bool, delta int) { + if is4 { + t.size4 += delta + return + } + t.size6 += delta +} + +// insert adds or updates a prefix-value pair in the routing table. +// If the prefix already exists, its value is updated; otherwise a new entry is created. +// Invalid prefixes are silently ignored. +// +// The prefix is automatically canonicalized using pfx.Masked() to ensure +// consistent behavior regardless of host bits in the input. +func (t *Table[V]) insert(pfx netip.Prefix, val V) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + if exists := n.Insert(pfx, val, 0); exists { + return + } + + // true insert, update size + t.sizeUpdate(is4, 1) +} + +// insertPersist is similar to insert but the receiver isn't modified. +// +// All nodes touched during insert are cloned and a new Table is returned. +// This is not a full [Table.Clone], all untouched nodes are still referenced +// from both Tables. +// +// If the payload type V contains pointers or needs deep copying, +// implement: +// +// func (v V) Clone() V +// +// The bart package detects this via structural typing and deep‑copies +// values during persistent ops. +// +// Due to cloning overhead this is significantly slower than insert, +// typically taking μsec instead of nsec. +func (t *Table[V]) insertPersist(pfx netip.Prefix, val V) *Table[V] { + if !pfx.IsValid() { + return t + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + // share size counters; root nodes cloned selectively. + pt := &Table[V]{ + size4: t.size4, + size6: t.size6, + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // Clone root node corresponding to the IP version, for copy-on-write. + n := &pt.root4 + + if is4 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + pt.root6 = t.root6 + } else { + pt.root4 = t.root4 + pt.root6 = *t.root6.CloneFlat(cloneFn) + + n = &pt.root6 + } + + if !n.InsertPersist(cloneFn, pfx, val, 0) { + pt.sizeUpdate(is4, 1) + } + + return pt +} + +// Delete removes the exact prefix pfx from the table in-place. +// +// This is an exact-match operation (no LPM). If pfx exists, the entry is +// removed. If pfx does not exist or pfx is invalid, the table is left unchanged. +// +// The prefix is canonicalized (Masked) before lookup. +func (t *Table[V]) Delete(pfx netip.Prefix) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + if exists := n.Delete(pfx); exists { + t.sizeUpdate(is4, -1) + } +} + +// Get performs an exact-prefix lookup and returns whether the exact +// prefix exists. The prefix is canonicalized (Masked) before lookup. +// +// This is an exact-match operation (no LPM). The prefix must match exactly +// in both address and prefix length to be found. If pfx exists, the +// associated value (zero value for Lite) and found=true is returned. +// If pfx does not exist or pfx is invalid, the zero value for V and +// exists=false is returned. +// +// For longest-prefix-match (LPM) lookups, use Contains(ip), Lookup(ip), +// LookupPrefix(pfx) or LookupPrefixLPM(pfx) instead. +func (t *Table[V]) Get(pfx netip.Prefix) (val V, exists bool) { + if !pfx.IsValid() { + return val, exists + } + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + return n.Get(pfx) +} + +// DeletePersist is similar to Delete but does not modify the receiver. +// +// It performs a copy-on-write delete operation, cloning all nodes touched during +// deletion and returning a new Table reflecting the change. +// +// If the prefix is invalid or doesn't exist, the original table is +// returned unchanged. +// +// If the payload type V contains pointers or requires deep copying, +// it must implement the Clone method for correct cloning. +// +// Due to cloning overhead this is significantly slower than Delete, +// typically taking μsec instead of nsec. +func (t *Table[V]) DeletePersist(pfx netip.Prefix) *Table[V] { + if !pfx.IsValid() { + return t + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + // Preflight check: avoid cloning if prefix doesn't exist + n := t.rootNodeByVersion(is4) + if _, found := n.Get(pfx); !found { + return t + } + + // share size counters; root nodes cloned selectively. + pt := &Table[V]{ + size4: t.size4, + size6: t.size6, + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // Clone root node corresponding to the IP version, for copy-on-write. + if is4 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + pt.root6 = t.root6 + n = &pt.root4 + } else { + pt.root4 = t.root4 + pt.root6 = *t.root6.CloneFlat(cloneFn) + n = &pt.root6 + } + + if exists := n.DeletePersist(cloneFn, pfx); exists { + pt.sizeUpdate(is4, -1) + } + + return pt +} + +// ModifyPersist is similar to Modify but the receiver isn't modified and +// a new *Table is returned. +func (t *Table[V]) ModifyPersist(pfx netip.Prefix, cb func(_ V, ok bool) (_ V, del bool)) *Table[V] { + if !pfx.IsValid() { + return t + } + + // make a cheap test in front of expensive operation + oldVal, ok := t.Get(pfx) + val := oldVal + + // to clone or not to clone ... + cloneFn := value.CloneFnFactory[V]() + if cloneFn != nil && ok { + val = cloneFn(oldVal) + } + + newVal, del := cb(val, ok) + + switch { + case !ok && del: // no-op + return t + + case !ok && !del: // insert + return t.InsertPersist(pfx, newVal) + + case ok && !del: // update + return t.InsertPersist(pfx, newVal) + + case ok && del: // delete + return t.DeletePersist(pfx) + } + + panic("unreachable") +} + +// Supernets returns an iterator over all supernet routes that cover the given prefix pfx. +// +// The traversal searches both exact-length and shorter (less specific) prefixes that +// include pfx. Starting from the most specific position in the trie, +// it walks upward through parent nodes and yields any matching entries found at each level. +// +// The iteration order is reverse-CIDR: from longest prefix match (LPM) towards +// least-specific routes. +// +// This can be used to enumerate all covering supernet routes in routing-based +// policy engines, diagnostics tools, or fallback resolution logic. +// +// Example: +// +// for supernet, val := range table.Supernets(netip.MustParsePrefix("192.0.2.128/25")) { +// fmt.Println("Covered by:", supernet, "->", val) +// } +// +// The iteration can be stopped early by breaking from the range loop. +// Returns an empty iterator if the prefix is invalid. +func (t *Table[V]) Supernets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if !pfx.IsValid() { + return + } + + // canonicalize the prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + n.Supernets(pfx, yield) + } +} + +// Subnets returns an iterator over all subnets of the given prefix +// in natural CIDR sort order. This includes prefixes of the same length +// (exact match) and longer (more specific) prefixes that are contained +// within the given prefix. +// +// Example: +// +// for sub, val := range table.Subnets(netip.MustParsePrefix("10.0.0.0/8")) { +// fmt.Println("Covered:", sub, "->", val) +// } +// +// The iteration can be stopped early by breaking from the range loop. +// Returns an empty iterator if the prefix is invalid. +func (t *Table[V]) Subnets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if !pfx.IsValid() { + return + } + + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + n.Subnets(pfx, yield) + } +} + +// OverlapsPrefix reports whether any prefix in the routing table overlaps with +// the given prefix. Two prefixes overlap if they share any IP addresses. +// +// The check is bidirectional: it returns true if the input prefix is covered by an existing +// route, or if any stored route is itself contained within the input prefix. +// +// Internally, the function normalizes the prefix and descends the relevant trie branch, +// using stride-based logic to identify overlap without performing a full lookup. +// +// This is useful for containment tests, route validation, or policy checks using prefix +// semantics without retrieving exact matches. +func (t *Table[V]) OverlapsPrefix(pfx netip.Prefix) bool { + if !pfx.IsValid() { + return false + } + + // canonicalize the prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + return n.OverlapsPrefixAtDepth(pfx, 0) +} + +// Overlaps reports whether any route in the receiver table overlaps +// with a route in the other table, in either direction. +// +// The overlap check is bidirectional: it returns true if any IP prefix +// in the receiver is covered by the other table, or vice versa. +// This includes partial overlaps, exact matches, and supernet/subnet relationships. +// +// Both IPv4 and IPv6 route trees are compared independently. If either +// tree has overlapping routes, the function returns true. +// +// This is useful for conflict detection, policy enforcement, +// or validating mutually exclusive routing domains. +func (t *Table[V]) Overlaps(o *Table[V]) bool { + return t.Overlaps4(o) || t.Overlaps6(o) +} + +// Overlaps4 is like [Table.Overlaps] but for the v4 routing table only. +func (t *Table[V]) Overlaps4(o *Table[V]) bool { + if t.size4 == 0 || o.size4 == 0 { + return false + } + return t.root4.Overlaps(&o.root4, 0) +} + +// Overlaps6 is like [Table.Overlaps] but for the v6 routing table only. +func (t *Table[V]) Overlaps6(o *Table[V]) bool { + if t.size6 == 0 || o.size6 == 0 { + return false + } + return t.root6.Overlaps(&o.root6, 0) +} + +// Union merges another routing table into the receiver table, modifying it in-place. +// +// All prefixes and values from the other table (o) are inserted into the receiver. +// If a duplicate prefix exists in both tables, the value from o replaces the existing entry. +// This duplicate is shallow-copied by default, but if the value type V implements the +// Clone method, the value is deeply cloned before insertion. See also Table.Clone. +func (t *Table[V]) Union(o *Table[V]) { + // panics on nil receiver + _ = t.size4 + + // panics on nil argument + if o.size4 == 0 && o.size6 == 0 { + return + } + // t is unchanged + if o == t { + return + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + dup4 := t.root4.UnionRec(cloneFn, &o.root4, 0) + dup6 := t.root6.UnionRec(cloneFn, &o.root6, 0) + + t.size4 += o.size4 - dup4 + t.size6 += o.size6 - dup6 +} + +// UnionPersist is similar to [Union] but the receiver isn't modified. +// +// All nodes touched during union are cloned and a new *Table is returned. +// If o is empty, no nodes are touched and the receiver may be +// returned unchanged. +func (t *Table[V]) UnionPersist(o *Table[V]) *Table[V] { + // panics on nil receiver + _ = t.size4 + + // panics on nil argument + if o.size4 == 0 && o.size6 == 0 { + return t + } + if o == t { + return t + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // new Table with root nodes just copied. + pt := &Table[V]{ + root4: t.root4, + root6: t.root6, + // + size4: t.size4, + size6: t.size6, + } + + // only clone the root node if there is something to union + if o.size4 != 0 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + } + if o.size6 != 0 { + pt.root6 = *t.root6.CloneFlat(cloneFn) + } + + dup4 := pt.root4.UnionRecPersist(cloneFn, &o.root4, 0) + dup6 := pt.root6.UnionRecPersist(cloneFn, &o.root6, 0) + + pt.size4 += o.size4 - dup4 + pt.size6 += o.size6 - dup6 + + return pt +} + +// Equal checks whether two tables are structurally and semantically equal. +// It ensures both trees (IPv4-based and IPv6-based) have the same sizes and +// recursively compares their root nodes. +// +// If V implements an `Equal(V) bool` method, its custom equality logic is used. +// Otherwise, values are compared directly using the == operator. +// +// Note: If V implements `Equal(V) bool` with a pointer receiver, the Equal +// method should handle nil receivers gracefully. +// +// ATTENTION: If V is not comparable at runtime (such as a slice or map without an `Equal` +// method), a runtime panic will occur. +func (t *Table[V]) Equal(o *Table[V]) bool { + if t.size4 != o.size4 || t.size6 != o.size6 { + return false + } + if o == t { + return true + } + + return t.root4.EqualRec(&o.root4) && t.root6.EqualRec(&o.root6) +} + +// Clone returns a copy of the routing table. +// The payload of type V is shallow copied by default. To enable deep copying, +// implement the following method on your value type: +// +// Clone() V +// +// Example: +// +// type MyValue struct { Data []byte } +// func (v MyValue) Clone() MyValue { +// return MyValue{Data: slices.Clone(v.Data)} +// } +// +// The bart package will automatically detect and use this method via Go's +// structural typing. +// +// Note: If V implements Clone() V with a pointer receiver, the Clone +// method should handle nil receivers gracefully. +func (t *Table[V]) Clone() *Table[V] { + c := new(Table[V]) + + cloneFn := value.CloneFnFactory[V]() + + c.root4 = *t.root4.CloneRec(cloneFn) + c.root6 = *t.root6.CloneRec(cloneFn) + + c.size4 = t.size4 + c.size6 = t.size6 + + return c +} + +// Size returns the prefix count. +func (t *Table[V]) Size() int { + return t.size4 + t.size6 +} + +// Size4 returns the IPv4 prefix count. +func (t *Table[V]) Size4() int { + return t.size4 +} + +// Size6 returns the IPv6 prefix count. +func (t *Table[V]) Size6() int { + return t.size6 +} + +// All returns an iterator over all prefix–value pairs in the table. +// +// The iteration order is unspecified and may vary between calls; for a stable order, +// use [Table.AllSorted]. +// +// IMPORTANT: Modifying the table during iteration is not allowed, +// as this would interfere with the internal traversal and may corrupt or +// prematurely terminate the iteration. +func (t *Table[V]) All() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRec(stridePath{}, 0, true, yield) && t.root6.AllRec(stridePath{}, 0, false, yield) + } +} + +// All4 is like [Table.All] but only for the v4 routing table. +func (t *Table[V]) All4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRec(stridePath{}, 0, true, yield) + } +} + +// All6 is like [Table.All] but only for the v6 routing table. +func (t *Table[V]) All6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root6.AllRec(stridePath{}, 0, false, yield) + } +} + +// AllSorted is like [Table.All] but the iteration is ordered in canonical +// CIDR prefix sort order. +func (t *Table[V]) AllSorted() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRecSorted(stridePath{}, 0, true, yield) && + t.root6.AllRecSorted(stridePath{}, 0, false, yield) + } +} + +// AllSorted4 is like [Table.AllSorted] but only for the v4 routing table. +func (t *Table[V]) AllSorted4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRecSorted(stridePath{}, 0, true, yield) + } +} + +// AllSorted6 is like [Table.AllSorted] but only for the v6 routing table. +func (t *Table[V]) AllSorted6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root6.AllRecSorted(stridePath{}, 0, false, yield) + } +} + +// Fprint writes a hierarchical tree diagram of the ordered CIDRs +// with default formatted payload V to w. +// +// The order from top to bottom is in ascending order of the prefix address +// and the subtree structure is determined by the CIDRs coverage. +// +// ▼ +// ├─ 10.0.0.0/8 (V) +// │ ├─ 10.0.0.0/24 (V) +// │ └─ 10.0.1.0/24 (V) +// ├─ 127.0.0.0/8 (V) +// │ └─ 127.0.0.1/32 (V) +// ├─ 169.254.0.0/16 (V) +// ├─ 172.16.0.0/12 (V) +// └─ 192.168.0.0/16 (V) +// └─ 192.168.1.0/24 (V) +// ▼ +// └─ ::/0 (V) +// ├─ ::1/128 (V) +// ├─ 2000::/3 (V) +// │ └─ 2001:db8::/32 (V) +// └─ fe80::/10 (V) +func (t *Table[V]) Fprint(w io.Writer) error { + if w == nil && t != nil { + return fmt.Errorf("nil writer") + } + + // v4 + if err := t.fprint(w, true); err != nil { + return err + } + + // v6 + if err := t.fprint(w, false); err != nil { + return err + } + + return nil +} + +// fprint is the version dependent adapter to fprintRec. +func (t *Table[V]) fprint(w io.Writer, is4 bool) error { + n := t.rootNodeByVersion(is4) + if n.IsEmpty() { + return nil + } + + if _, err := fmt.Fprint(w, "▼\n"); err != nil { + return err + } + + startParent := nodes.TrieItem[V]{ + Node: nil, + Idx: 0, + Path: stridePath{}, + Is4: is4, + } + + return n.FprintRec(w, startParent, "") +} + +// MarshalText implements the [encoding.TextMarshaler] interface, +// just a wrapper for [Table.Fprint]. +func (t *Table[V]) MarshalText() ([]byte, error) { + w := new(bytes.Buffer) + if err := t.Fprint(w); err != nil { + return nil, err + } + + return w.Bytes(), nil +} + +// MarshalJSON dumps the table into two sorted lists: for ipv4 and ipv6. +// Every root and subnet is an array, not a map, because the order matters. +func (t *Table[V]) MarshalJSON() ([]byte, error) { + result := struct { + Ipv4 []DumpListNode[V] `json:"ipv4,omitempty"` + Ipv6 []DumpListNode[V] `json:"ipv6,omitempty"` + }{ + Ipv4: t.DumpList4(), + Ipv6: t.DumpList6(), + } + + buf, err := json.Marshal(result) + if err != nil { + return nil, err + } + + return buf, nil +} + +// DumpList4 dumps the ipv4 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build the text or JSON serialization. +func (t *Table[V]) DumpList4() []DumpListNode[V] { + return t.dumpListRec(&t.root4, 0, stridePath{}, 0, true) +} + +// DumpList6 dumps the ipv6 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build custom JSON representation. +func (t *Table[V]) DumpList6() []DumpListNode[V] { + return t.dumpListRec(&t.root6, 0, stridePath{}, 0, false) +} + +// dumpListRec, build the data structure rec-descent with the help of directItemsRec. +// anyNode is nodes.BartNode, nodes.FastNode or nodes.LiteNode +func (t *Table[V]) dumpListRec(anyNode any, parentIdx uint8, path stridePath, depth int, is4 bool) []DumpListNode[V] { + // recursion stop condition + if anyNode == nil { + return nil + } + + // the same method is generated for all table types, therefore + // type assert to the smallest needed interface. + // The panic on wrong type assertion is by intention, MUST NOT happen + n := anyNode.(interface { + DirectItemsRec(uint8, stridePath, int, bool) []nodes.TrieItem[V] + }) + + directItems := n.DirectItemsRec(parentIdx, path, depth, is4) + + // sort the items by prefix + slices.SortFunc(directItems, func(a, b nodes.TrieItem[V]) int { + return nodes.CmpPrefix(a.Cidr, b.Cidr) + }) + + dumpNodes := make([]DumpListNode[V], 0, len(directItems)) + + for _, item := range directItems { + dumpNodes = append(dumpNodes, DumpListNode[V]{ + CIDR: item.Cidr, + Value: item.Val, + // build it rec-descent, item.Node is also from type any + Subnets: t.dumpListRec(item.Node, item.Idx, item.Path, item.Depth, is4), + }) + } + + return dumpNodes +} + +// dumpString is just a wrapper for dump. +func (t *Table[V]) dumpString() string { + w := new(strings.Builder) + t.dump(w) + + return w.String() +} + +// dump the table structure and all the nodes to w. +func (t *Table[V]) dump(w io.Writer) { + if t.size4 > 0 { + stats := t.root4.StatsRec() + fmt.Fprintln(w) + fmt.Fprintf(w, "### IPv4: size(%d), subnodes(%d), prefixes(%d), leaves(%d), fringes(%d)", + t.size4, stats.SubNodes, stats.Prefixes, stats.Leaves, stats.Fringes) + + t.root4.DumpRec(w, stridePath{}, 0, true) + } + + if t.size6 > 0 { + stats := t.root6.StatsRec() + fmt.Fprintln(w) + fmt.Fprintf(w, "### IPv6: size(%d), subnodes(%d), prefixes(%d), leaves(%d), fringes(%d)", + t.size6, stats.SubNodes, stats.Prefixes, stats.Leaves, stats.Fringes) + + t.root6.DumpRec(w, stridePath{}, 0, false) + } +} diff --git a/vendor/github.com/gaissmai/bart/base_index.go b/vendor/github.com/gaissmai/bart/base_index.go deleted file mode 100644 index 561c0f4..0000000 --- a/vendor/github.com/gaissmai/bart/base_index.go +++ /dev/null @@ -1,595 +0,0 @@ -// Copyright (c) 2024 Karl Gaissmaier -// SPDX-License-Identifier: MIT - -// Please read the ART paper ./doc/artlookup.pdf -// to understand the baseIndex algorithm. - -package bart - -// netmask for bits -// -// 0b0000_0000, // bits == 0 -// 0b1000_0000, // bits == 1 -// 0b1100_0000, // bits == 2 -// 0b1110_0000, // bits == 3 -// 0b1111_0000, // bits == 4 -// 0b1111_1000, // bits == 5 -// 0b1111_1100, // bits == 6 -// 0b1111_1110, // bits == 7 -// 0b1111_1111, // bits == 8 -func netMask(bits int) uint8 { - return 0b1111_1111 << (8 - bits) -} - -// baseIndex of the first host route 0/8: pfxToIdx(0,8) -const firstHostIdx = 256 - -// pfxToIdx, maps a prefix table as a 'complete binary tree'. -func pfxToIdx(octet byte, prefixLen int) uint { - return uint(octet>>(strideLen-prefixLen)) + (1 << prefixLen) -} - -// hostIndex, just pfxToIdx(octet, 8) but faster. -func hostIndex(octet uint) uint { - return octet + firstHostIdx -} - -// cmpIndexRank, sort indexes in prefix sort order. -func cmpIndexRank(aIdx, bIdx uint) int { - // convert idx to prefix - aOctet, aBits := idxToPfx(aIdx) - bOctet, bBits := idxToPfx(bIdx) - - // cmp the prefixes, first by address and then by bits - if aOctet == bOctet { - if aBits <= bBits { - return -1 - } - - return 1 - } - - if aOctet < bOctet { - return -1 - } - - return 1 -} - -// idxToPfx returns the octet and prefix len of baseIdx. -// It's the inverse to pfxToIdx. -func idxToPfx(idx uint) (octet byte, pfxLen int) { - return baseIdxLookupTbl[idx].octet, int(baseIdxLookupTbl[idx].pfxLen) -} - -// baseIdxLookupTbl, maps back from idx => octet/bits -// -// Use the pre computed lookup table, the func baseIndexToPrefix is too slow -// in comparison to an array access. -// -// func baseIndexToPrefix(idx uint) (octet byte, pfxLen int) { -// nlz := bits.LeadingZeros(idx) -// pfxLen = strconv.IntSize - nlz - 1 -// octet = byte((idx & (0xFF >> (8 - pfxLen))) << (8 - pfxLen)) -// return octet, pfxLen -// } -var baseIdxLookupTbl = [512]struct { - octet byte - pfxLen int8 -}{ - {0, -1}, // idx == 0, invalid - {0, 0}, // idx == 1 - {0, 1}, // idx == 2 - {128, 1}, // idx == 3, e.g. 128.0.0.0/1, 8000::/1 - {0, 2}, // idx == 4 - {64, 2}, // idx == 5 - {128, 2}, // idx == 6 - {192, 2}, // idx == 7 - {0, 3}, // idx == 8 - {32, 3}, // idx == 9 - {64, 3}, // idx == 10 - {96, 3}, // idx == 11 - {128, 3}, // idx == 12 - {160, 3}, // idx == 13 - {192, 3}, // idx == 14 - {224, 3}, // idx == 15 - {0, 4}, // idx == 16 - {16, 4}, // idx == 17 - {32, 4}, // idx == 18 - {48, 4}, // idx == 19 - {64, 4}, // idx == 20 - {80, 4}, // idx == 21 - {96, 4}, // idx == 22 - {112, 4}, // idx == 23 - {128, 4}, // idx == 24 - {144, 4}, // idx == 25 - {160, 4}, // idx == 26 - {176, 4}, // idx == 27 - {192, 4}, // idx == 28 - {208, 4}, // idx == 29 - {224, 4}, // idx == 30 - {240, 4}, // idx == 31 - {0, 5}, // idx == 32 - {8, 5}, // idx == 33 - {16, 5}, // idx == 34 - {24, 5}, // idx == 35 - {32, 5}, // idx == 36 - {40, 5}, // idx == 37 - {48, 5}, // idx == 38 - {56, 5}, // idx == 39 - {64, 5}, // idx == 40 - {72, 5}, // idx == 41 - {80, 5}, // idx == 42 - {88, 5}, // idx == 43 - {96, 5}, // idx == 44 - {104, 5}, // idx == 45 - {112, 5}, // idx == 46 - {120, 5}, // idx == 47 - {128, 5}, // idx == 48 - {136, 5}, // idx == 49 - {144, 5}, // idx == 50 - {152, 5}, // idx == 51 - {160, 5}, // idx == 52 - {168, 5}, // idx == 53 - {176, 5}, // idx == 54 - {184, 5}, // idx == 55 - {192, 5}, // idx == 56 - {200, 5}, // idx == 57 - {208, 5}, // idx == 58 - {216, 5}, // idx == 59 - {224, 5}, // idx == 60 - {232, 5}, // idx == 61 - {240, 5}, // idx == 62 - {248, 5}, // idx == 63 - {0, 6}, // idx == 64 - {4, 6}, // idx == 65 - {8, 6}, // idx == 66 - {12, 6}, // idx == 67 - {16, 6}, // idx == 68 - {20, 6}, // idx == 69 - {24, 6}, // idx == 70 - {28, 6}, // idx == 71 - {32, 6}, // idx == 72 - {36, 6}, // idx == 73 - {40, 6}, // idx == 74 - {44, 6}, // idx == 75 - {48, 6}, // idx == 76 - {52, 6}, // idx == 77 - {56, 6}, // idx == 78 - {60, 6}, // idx == 79 - {64, 6}, // idx == 80 - {68, 6}, // idx == 81 - {72, 6}, // idx == 82 - {76, 6}, // idx == 83 - {80, 6}, // idx == 84 - {84, 6}, // idx == 85 - {88, 6}, // idx == 86 - {92, 6}, // idx == 87 - {96, 6}, // idx == 88 - {100, 6}, // idx == 89 - {104, 6}, // idx == 90 - {108, 6}, // idx == 91 - {112, 6}, // idx == 92 - {116, 6}, // idx == 93 - {120, 6}, // idx == 94 - {124, 6}, // idx == 95 - {128, 6}, // idx == 96 - {132, 6}, // idx == 97 - {136, 6}, // idx == 98 - {140, 6}, // idx == 99 - {144, 6}, // idx == 100 - {148, 6}, // idx == 101 - {152, 6}, // idx == 102 - {156, 6}, // idx == 103 - {160, 6}, // idx == 104 - {164, 6}, // idx == 105 - {168, 6}, // idx == 106 - {172, 6}, // idx == 107 - {176, 6}, // idx == 108 - {180, 6}, // idx == 109 - {184, 6}, // idx == 110 - {188, 6}, // idx == 111 - {192, 6}, // idx == 112 - {196, 6}, // idx == 113 - {200, 6}, // idx == 114 - {204, 6}, // idx == 115 - {208, 6}, // idx == 116 - {212, 6}, // idx == 117 - {216, 6}, // idx == 118 - {220, 6}, // idx == 119 - {224, 6}, // idx == 120 - {228, 6}, // idx == 121 - {232, 6}, // idx == 122 - {236, 6}, // idx == 123 - {240, 6}, // idx == 124 - {244, 6}, // idx == 125 - {248, 6}, // idx == 126 - {252, 6}, // idx == 127 - {0, 7}, // idx == 128 - {2, 7}, // idx == 129 - {4, 7}, // idx == 130 - {6, 7}, // idx == 131 - {8, 7}, // idx == 132 - {10, 7}, // idx == 133 - {12, 7}, // idx == 134 - {14, 7}, // idx == 135 - {16, 7}, // idx == 136 - {18, 7}, // idx == 137 - {20, 7}, // idx == 138 - {22, 7}, // idx == 139 - {24, 7}, // idx == 140 - {26, 7}, // idx == 141 - {28, 7}, // idx == 142 - {30, 7}, // idx == 143 - {32, 7}, // idx == 144 - {34, 7}, // idx == 145 - {36, 7}, // idx == 146 - {38, 7}, // idx == 147 - {40, 7}, // idx == 148 - {42, 7}, // idx == 149 - {44, 7}, // idx == 150 - {46, 7}, // idx == 151 - {48, 7}, // idx == 152 - {50, 7}, // idx == 153 - {52, 7}, // idx == 154 - {54, 7}, // idx == 155 - {56, 7}, // idx == 156 - {58, 7}, // idx == 157 - {60, 7}, // idx == 158 - {62, 7}, // idx == 159 - {64, 7}, // idx == 160 - {66, 7}, // idx == 161 - {68, 7}, // idx == 162 - {70, 7}, // idx == 163 - {72, 7}, // idx == 164 - {74, 7}, // idx == 165 - {76, 7}, // idx == 166 - {78, 7}, // idx == 167 - {80, 7}, // idx == 168 - {82, 7}, // idx == 169 - {84, 7}, // idx == 170 - {86, 7}, // idx == 171 - {88, 7}, // idx == 172 - {90, 7}, // idx == 173 - {92, 7}, // idx == 174 - {94, 7}, // idx == 175 - {96, 7}, // idx == 176 - {98, 7}, // idx == 177 - {100, 7}, // idx == 178 - {102, 7}, // idx == 179 - {104, 7}, // idx == 180 - {106, 7}, // idx == 181 - {108, 7}, // idx == 182 - {110, 7}, // idx == 183 - {112, 7}, // idx == 184 - {114, 7}, // idx == 185 - {116, 7}, // idx == 186 - {118, 7}, // idx == 187 - {120, 7}, // idx == 188 - {122, 7}, // idx == 189 - {124, 7}, // idx == 190 - {126, 7}, // idx == 191 - {128, 7}, // idx == 192 - {130, 7}, // idx == 193 - {132, 7}, // idx == 194 - {134, 7}, // idx == 195 - {136, 7}, // idx == 196 - {138, 7}, // idx == 197 - {140, 7}, // idx == 198 - {142, 7}, // idx == 199 - {144, 7}, // idx == 200 - {146, 7}, // idx == 201 - {148, 7}, // idx == 202 - {150, 7}, // idx == 203 - {152, 7}, // idx == 204 - {154, 7}, // idx == 205 - {156, 7}, // idx == 206 - {158, 7}, // idx == 207 - {160, 7}, // idx == 208 - {162, 7}, // idx == 209 - {164, 7}, // idx == 210 - {166, 7}, // idx == 211 - {168, 7}, // idx == 212 - {170, 7}, // idx == 213 - {172, 7}, // idx == 214 - {174, 7}, // idx == 215 - {176, 7}, // idx == 216 - {178, 7}, // idx == 217 - {180, 7}, // idx == 218 - {182, 7}, // idx == 219 - {184, 7}, // idx == 220 - {186, 7}, // idx == 221 - {188, 7}, // idx == 222 - {190, 7}, // idx == 223 - {192, 7}, // idx == 224 - {194, 7}, // idx == 225 - {196, 7}, // idx == 226 - {198, 7}, // idx == 227 - {200, 7}, // idx == 228 - {202, 7}, // idx == 229 - {204, 7}, // idx == 230 - {206, 7}, // idx == 231 - {208, 7}, // idx == 232 - {210, 7}, // idx == 233 - {212, 7}, // idx == 234 - {214, 7}, // idx == 235 - {216, 7}, // idx == 236 - {218, 7}, // idx == 237 - {220, 7}, // idx == 238 - {222, 7}, // idx == 239 - {224, 7}, // idx == 240 - {226, 7}, // idx == 241 - {228, 7}, // idx == 242 - {230, 7}, // idx == 243 - {232, 7}, // idx == 244 - {234, 7}, // idx == 245 - {236, 7}, // idx == 246 - {238, 7}, // idx == 247 - {240, 7}, // idx == 248 - {242, 7}, // idx == 249 - {244, 7}, // idx == 250 - {246, 7}, // idx == 251 - {248, 7}, // idx == 252 - {250, 7}, // idx == 253 - {252, 7}, // idx == 254 - {254, 7}, // idx == 255 - // - // host routes, pfxLen == 8 - // - {0, 8}, // idx == 256, e.g. 0.0.0.0/8, ::/8 - {1, 8}, // idx == 257 - {2, 8}, // idx == 258 - {3, 8}, // idx == 259 - {4, 8}, // idx == 260 - {5, 8}, // idx == 261 - {6, 8}, // idx == 262 - {7, 8}, // idx == 263 - {8, 8}, // idx == 264 - {9, 8}, // idx == 265 - {10, 8}, // idx == 266, 10.0.0.0/8, 0a00::/8 - {11, 8}, // idx == 267 - {12, 8}, // idx == 268 - {13, 8}, // idx == 269 - {14, 8}, // idx == 270 - {15, 8}, // idx == 271 - {16, 8}, // idx == 272 - {17, 8}, // idx == 273 - {18, 8}, // idx == 274 - {19, 8}, // idx == 275 - {20, 8}, // idx == 276 - {21, 8}, // idx == 277 - {22, 8}, // idx == 278 - {23, 8}, // idx == 279 - {24, 8}, // idx == 280 - {25, 8}, // idx == 281 - {26, 8}, // idx == 282 - {27, 8}, // idx == 283 - {28, 8}, // idx == 284 - {29, 8}, // idx == 285 - {30, 8}, // idx == 286 - {31, 8}, // idx == 287 - {32, 8}, // idx == 288 - {33, 8}, // idx == 289 - {34, 8}, // idx == 290 - {35, 8}, // idx == 291 - {36, 8}, // idx == 292 - {37, 8}, // idx == 293 - {38, 8}, // idx == 294 - {39, 8}, // idx == 295 - {40, 8}, // idx == 296 - {41, 8}, // idx == 297 - {42, 8}, // idx == 298 - {43, 8}, // idx == 299 - {44, 8}, // idx == 300 - {45, 8}, // idx == 301 - {46, 8}, // idx == 302 - {47, 8}, // idx == 303 - {48, 8}, // idx == 304 - {49, 8}, // idx == 305 - {50, 8}, // idx == 306 - {51, 8}, // idx == 307 - {52, 8}, // idx == 308 - {53, 8}, // idx == 309 - {54, 8}, // idx == 310 - {55, 8}, // idx == 311 - {56, 8}, // idx == 312 - {57, 8}, // idx == 313 - {58, 8}, // idx == 314 - {59, 8}, // idx == 315 - {60, 8}, // idx == 316 - {61, 8}, // idx == 317 - {62, 8}, // idx == 318 - {63, 8}, // idx == 319 - {64, 8}, // idx == 320 - {65, 8}, // idx == 321 - {66, 8}, // idx == 322 - {67, 8}, // idx == 323 - {68, 8}, // idx == 324 - {69, 8}, // idx == 325 - {70, 8}, // idx == 326 - {71, 8}, // idx == 327 - {72, 8}, // idx == 328 - {73, 8}, // idx == 329 - {74, 8}, // idx == 330 - {75, 8}, // idx == 331 - {76, 8}, // idx == 332 - {77, 8}, // idx == 333 - {78, 8}, // idx == 334 - {79, 8}, // idx == 335 - {80, 8}, // idx == 336 - {81, 8}, // idx == 337 - {82, 8}, // idx == 338 - {83, 8}, // idx == 339 - {84, 8}, // idx == 340 - {85, 8}, // idx == 341 - {86, 8}, // idx == 342 - {87, 8}, // idx == 343 - {88, 8}, // idx == 344 - {89, 8}, // idx == 345 - {90, 8}, // idx == 346 - {91, 8}, // idx == 347 - {92, 8}, // idx == 348 - {93, 8}, // idx == 349 - {94, 8}, // idx == 350 - {95, 8}, // idx == 351 - {96, 8}, // idx == 352 - {97, 8}, // idx == 353 - {98, 8}, // idx == 354 - {99, 8}, // idx == 355 - {100, 8}, // idx == 356 - {101, 8}, // idx == 357 - {102, 8}, // idx == 358 - {103, 8}, // idx == 359 - {104, 8}, // idx == 360 - {105, 8}, // idx == 361 - {106, 8}, // idx == 362 - {107, 8}, // idx == 363 - {108, 8}, // idx == 364 - {109, 8}, // idx == 365 - {110, 8}, // idx == 366 - {111, 8}, // idx == 367 - {112, 8}, // idx == 368 - {113, 8}, // idx == 369 - {114, 8}, // idx == 370 - {115, 8}, // idx == 371 - {116, 8}, // idx == 372 - {117, 8}, // idx == 373 - {118, 8}, // idx == 374 - {119, 8}, // idx == 375 - {120, 8}, // idx == 376 - {121, 8}, // idx == 377 - {122, 8}, // idx == 378 - {123, 8}, // idx == 379 - {124, 8}, // idx == 380 - {125, 8}, // idx == 381 - {126, 8}, // idx == 382 - {127, 8}, // idx == 383 - {128, 8}, // idx == 384 - {129, 8}, // idx == 385 - {130, 8}, // idx == 386 - {131, 8}, // idx == 387 - {132, 8}, // idx == 388 - {133, 8}, // idx == 389 - {134, 8}, // idx == 390 - {135, 8}, // idx == 391 - {136, 8}, // idx == 392 - {137, 8}, // idx == 393 - {138, 8}, // idx == 394 - {139, 8}, // idx == 395 - {140, 8}, // idx == 396 - {141, 8}, // idx == 397 - {142, 8}, // idx == 398 - {143, 8}, // idx == 399 - {144, 8}, // idx == 400 - {145, 8}, // idx == 401 - {146, 8}, // idx == 402 - {147, 8}, // idx == 403 - {148, 8}, // idx == 404 - {149, 8}, // idx == 405 - {150, 8}, // idx == 406 - {151, 8}, // idx == 407 - {152, 8}, // idx == 408 - {153, 8}, // idx == 409 - {154, 8}, // idx == 410 - {155, 8}, // idx == 411 - {156, 8}, // idx == 412 - {157, 8}, // idx == 413 - {158, 8}, // idx == 414 - {159, 8}, // idx == 415 - {160, 8}, // idx == 416 - {161, 8}, // idx == 417 - {162, 8}, // idx == 418 - {163, 8}, // idx == 419 - {164, 8}, // idx == 420 - {165, 8}, // idx == 421 - {166, 8}, // idx == 422 - {167, 8}, // idx == 423 - {168, 8}, // idx == 424 - {169, 8}, // idx == 425 - {170, 8}, // idx == 426 - {171, 8}, // idx == 427 - {172, 8}, // idx == 428 - {173, 8}, // idx == 429 - {174, 8}, // idx == 430 - {175, 8}, // idx == 431 - {176, 8}, // idx == 432 - {177, 8}, // idx == 433 - {178, 8}, // idx == 434 - {179, 8}, // idx == 435 - {180, 8}, // idx == 436 - {181, 8}, // idx == 437 - {182, 8}, // idx == 438 - {183, 8}, // idx == 439 - {184, 8}, // idx == 440 - {185, 8}, // idx == 441 - {186, 8}, // idx == 442 - {187, 8}, // idx == 443 - {188, 8}, // idx == 444 - {189, 8}, // idx == 445 - {190, 8}, // idx == 446 - {191, 8}, // idx == 447 - {192, 8}, // idx == 448 - {193, 8}, // idx == 449 - {194, 8}, // idx == 450 - {195, 8}, // idx == 451 - {196, 8}, // idx == 452 - {197, 8}, // idx == 453 - {198, 8}, // idx == 454 - {199, 8}, // idx == 455 - {200, 8}, // idx == 456 - {201, 8}, // idx == 457 - {202, 8}, // idx == 458 - {203, 8}, // idx == 459 - {204, 8}, // idx == 460 - {205, 8}, // idx == 461 - {206, 8}, // idx == 462 - {207, 8}, // idx == 463 - {208, 8}, // idx == 464 - {209, 8}, // idx == 465 - {210, 8}, // idx == 466 - {211, 8}, // idx == 467 - {212, 8}, // idx == 468 - {213, 8}, // idx == 469 - {214, 8}, // idx == 470 - {215, 8}, // idx == 471 - {216, 8}, // idx == 472 - {217, 8}, // idx == 473 - {218, 8}, // idx == 474 - {219, 8}, // idx == 475 - {220, 8}, // idx == 476 - {221, 8}, // idx == 477 - {222, 8}, // idx == 478 - {223, 8}, // idx == 479 - {224, 8}, // idx == 480 - {225, 8}, // idx == 481 - {226, 8}, // idx == 482 - {227, 8}, // idx == 483 - {228, 8}, // idx == 484 - {229, 8}, // idx == 485 - {230, 8}, // idx == 486 - {231, 8}, // idx == 487 - {232, 8}, // idx == 488 - {233, 8}, // idx == 489 - {234, 8}, // idx == 490 - {235, 8}, // idx == 491 - {236, 8}, // idx == 492 - {237, 8}, // idx == 493 - {238, 8}, // idx == 494 - {239, 8}, // idx == 495 - {240, 8}, // idx == 496 - {241, 8}, // idx == 497 - {242, 8}, // idx == 498 - {243, 8}, // idx == 499 - {244, 8}, // idx == 500 - {245, 8}, // idx == 501 - {246, 8}, // idx == 502 - {247, 8}, // idx == 503 - {248, 8}, // idx == 504 - {249, 8}, // idx == 505 - {250, 8}, // idx == 506 - {251, 8}, // idx == 507 - {252, 8}, // idx == 508 - {253, 8}, // idx == 509 - {254, 8}, // idx == 510 - {255, 8}, // idx == 511 -} diff --git a/vendor/github.com/gaissmai/bart/common.go b/vendor/github.com/gaissmai/bart/common.go new file mode 100644 index 0000000..0b8d6ef --- /dev/null +++ b/vendor/github.com/gaissmai/bart/common.go @@ -0,0 +1,62 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +// Package bart provides high-performance Balanced Routing Tables (BART) +// for fast IP-to-CIDR lookups on IPv4 and IPv6 addresses. +// +// BART offers three table variants optimized for different use cases: +// +// - Lite: Memory-optimized with popcount-compressed sparse arrays +// - Table: Full-featured with popcount-compressed sparse arrays +// - Fast: Speed-optimized with additional rank caching +// +// The implementation is based on Knuth's ART algorithm with novel +// optimizations for memory efficiency and lookup speed. +// +// `Table` and `Lite` use popcount compression for memory efficiency, while +// `Fast` trades additional memory and slower updates for maximum lookup +// speed: a child-rank cache is maintained on every insert/delete, so +// lookups avoid popcount but updates pay the caching cost. +// +// BART excels at efficient set operations on routing tables including Union, +// Overlaps, Equal, Subnets, and Supernets with optimal complexity, making it +// ideal for large-scale IP prefix matching in ACLs, RIBs, FIBs, firewalls, +// and routers. +// +// All variants also support copy-on-write persistence. +// +// For complex or pointer value types, you must provide custom deep cloning +// using Go's structural typing, implementing the following method on your +// value type V: +// +// func (v V) Clone() V +// +// For custom Equality implement the following method on your value type V: +// +// func (v V) Equal(other V) bool +// +// The bart package detects the interface satisfaction automatically at +// runtime using type assertions. +package bart + +import ( + "net/netip" + + "github.com/gaissmai/bart/internal/nodes" + + // inlining hint, see also the TestInlineBitSet256Functions. + // without this silent import the BitSet256 functions are not inlined + _ "github.com/gaissmai/bart/internal/bitset" +) + +// stridePath is required in many places in the bart package and in +// internal/nodes. Aliased to keep the code readable. +type stridePath = nodes.StridePath + +// DumpListNode contains CIDR, Value and Subnets, representing the trie +// in a sorted, recursive representation, especially useful for serialization. +type DumpListNode[V any] struct { + CIDR netip.Prefix `json:"cidr"` + Value V `json:"value"` + Subnets []DumpListNode[V] `json:"subnets,omitempty"` +} diff --git a/vendor/github.com/gaissmai/bart/commonmethods_tmpl.go b/vendor/github.com/gaissmai/bart/commonmethods_tmpl.go new file mode 100644 index 0000000..2ed9ab0 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/commonmethods_tmpl.go @@ -0,0 +1,792 @@ +//go:build generate + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +//go:generate ./scripts/generate-table-methods.sh + +package bart + +// ### GENERATE DELETE START ### + +// stub code for generator types and methods +// useful for gopls during development, deleted during go generate + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "iter" + "net/netip" + "slices" + "strings" + + "github.com/gaissmai/bart/internal/nodes" + "github.com/gaissmai/bart/internal/value" +) + +type _NODE_TYPE[V any] struct{} + +type _TABLE_TYPE[V any] struct { + root4 _NODE_TYPE[V] + root6 _NODE_TYPE[V] + size4 int + size6 int +} + +func (n *_NODE_TYPE[V]) IsEmpty() (_ bool) { return } +func (n *_NODE_TYPE[V]) StatsRec() (_ nodes.StatsT) { return } +func (n *_NODE_TYPE[V]) PrefixCount() (_ int) { return } +func (n *_NODE_TYPE[V]) ChildCount() (_ int) { return } +func (n *_NODE_TYPE[V]) GetPrefix(uint8) (_ V, _ bool) { return } +func (n *_NODE_TYPE[V]) GetChild(uint8) (_ any, _ bool) { return } +func (n *_NODE_TYPE[V]) MustGetPrefix(uint8) (_ V) { return } +func (n *_NODE_TYPE[V]) MustGetChild(uint8) (_ any) { return } +func (n *_NODE_TYPE[V]) Insert(netip.Prefix, V, int) (_ bool) { return } +func (n *_NODE_TYPE[V]) Modify(netip.Prefix, func(V, bool) (V, bool)) (_ int) { return } +func (n *_NODE_TYPE[V]) Delete(netip.Prefix) (_ bool) { return } +func (n *_NODE_TYPE[V]) InsertPersist(nodes.CloneFunc[V], netip.Prefix, V, int) (_ bool) { return } +func (n *_NODE_TYPE[V]) DeletePersist(nodes.CloneFunc[V], netip.Prefix) (_ bool) { return } +func (n *_NODE_TYPE[V]) Get(netip.Prefix) (_ V, _ bool) { return } +func (n *_NODE_TYPE[V]) OverlapsPrefixAtDepth(netip.Prefix, int) (_ bool) { return } +func (n *_NODE_TYPE[V]) Overlaps(*_NODE_TYPE[V], int) (_ bool) { return } +func (n *_NODE_TYPE[V]) UnionRec(nodes.CloneFunc[V], *_NODE_TYPE[V], int) (_ int) { return } +func (n *_NODE_TYPE[V]) UnionRecPersist(nodes.CloneFunc[V], *_NODE_TYPE[V], int) (_ int) { return } +func (n *_NODE_TYPE[V]) EqualRec(*_NODE_TYPE[V]) (_ bool) { return } +func (n *_NODE_TYPE[V]) CloneRec(nodes.CloneFunc[V]) (_ *_NODE_TYPE[V]) { return } +func (n *_NODE_TYPE[V]) CloneFlat(nodes.CloneFunc[V]) (_ *_NODE_TYPE[V]) { return } +func (n *_NODE_TYPE[V]) GetChildAddrs(*[256]uint8) (_ []uint8) { return } +func (n *_NODE_TYPE[V]) GetIndices(*[256]uint8) (_ []uint8) { return } +func (n *_NODE_TYPE[V]) AllChildren() (_ iter.Seq2[uint8, any]) { return } +func (n *_NODE_TYPE[V]) AllIndices() (_ iter.Seq2[uint8, V]) { return } +func (n *_NODE_TYPE[V]) Contains(uint8) (_ bool) { return } +func (n *_NODE_TYPE[V]) Lookup(uint8) (_ V, _ bool) { return } +func (n *_NODE_TYPE[V]) LookupIdx(uint8) (_ uint8, _ V, _ bool) { return } +func (n *_NODE_TYPE[V]) Supernets(netip.Prefix, func(netip.Prefix, V) bool) { return } +func (n *_NODE_TYPE[V]) Subnets(netip.Prefix, func(netip.Prefix, V) bool) { return } +func (n *_NODE_TYPE[V]) FprintRec(io.Writer, nodes.TrieItem[V], string) (_ error) { return } +func (n *_NODE_TYPE[V]) DumpRec(io.Writer, stridePath, int, bool) { return } +func (n *_NODE_TYPE[V]) AllRec(stridePath, int, bool, func(netip.Prefix, V) bool) (_ bool) { + return +} + +func (n *_NODE_TYPE[V]) AllRecSorted(stridePath, int, bool, func(netip.Prefix, V) bool) (_ bool) { + return +} + +func (t *_TABLE_TYPE[V]) rootNodeByVersion(is4 bool) (_ *_NODE_TYPE[V]) { return } +func (t *_TABLE_TYPE[V]) InsertPersist(netip.Prefix, V) (_ *_TABLE_TYPE[V]) { return } + +// ### GENERATE DELETE END ### + +func (t *_TABLE_TYPE[V]) sizeUpdate(is4 bool, delta int) { + if is4 { + t.size4 += delta + return + } + t.size6 += delta +} + +// insert adds or updates a prefix-value pair in the routing table. +// If the prefix already exists, its value is updated; otherwise a new entry is created. +// Invalid prefixes are silently ignored. +// +// The prefix is automatically canonicalized using pfx.Masked() to ensure +// consistent behavior regardless of host bits in the input. +func (t *_TABLE_TYPE[V]) insert(pfx netip.Prefix, val V) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + if exists := n.Insert(pfx, val, 0); exists { + return + } + + // true insert, update size + t.sizeUpdate(is4, 1) +} + +// insertPersist is similar to insert but the receiver isn't modified. +// +// All nodes touched during insert are cloned and a new _TABLE_TYPE is returned. +// This is not a full [_TABLE_TYPE.Clone], all untouched nodes are still referenced +// from both Tables. +// +// If the payload type V contains pointers or needs deep copying, +// implement: +// +// func (v V) Clone() V +// +// The bart package detects this via structural typing and deep‑copies +// values during persistent ops. +// +// Due to cloning overhead this is significantly slower than insert, +// typically taking μsec instead of nsec. +func (t *_TABLE_TYPE[V]) insertPersist(pfx netip.Prefix, val V) *_TABLE_TYPE[V] { + if !pfx.IsValid() { + return t + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + // share size counters; root nodes cloned selectively. + pt := &_TABLE_TYPE[V]{ + size4: t.size4, + size6: t.size6, + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // Clone root node corresponding to the IP version, for copy-on-write. + n := &pt.root4 + + if is4 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + pt.root6 = t.root6 + } else { + pt.root4 = t.root4 + pt.root6 = *t.root6.CloneFlat(cloneFn) + + n = &pt.root6 + } + + if !n.InsertPersist(cloneFn, pfx, val, 0) { + pt.sizeUpdate(is4, 1) + } + + return pt +} + +// Delete removes the exact prefix pfx from the table in-place. +// +// This is an exact-match operation (no LPM). If pfx exists, the entry is +// removed. If pfx does not exist or pfx is invalid, the table is left unchanged. +// +// The prefix is canonicalized (Masked) before lookup. +func (t *_TABLE_TYPE[V]) Delete(pfx netip.Prefix) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + if exists := n.Delete(pfx); exists { + t.sizeUpdate(is4, -1) + } +} + +// Get performs an exact-prefix lookup and returns whether the exact +// prefix exists. The prefix is canonicalized (Masked) before lookup. +// +// This is an exact-match operation (no LPM). The prefix must match exactly +// in both address and prefix length to be found. If pfx exists, the +// associated value (zero value for Lite) and found=true is returned. +// If pfx does not exist or pfx is invalid, the zero value for V and +// exists=false is returned. +// +// For longest-prefix-match (LPM) lookups, use Contains(ip), Lookup(ip), +// LookupPrefix(pfx) or LookupPrefixLPM(pfx) instead. +func (t *_TABLE_TYPE[V]) Get(pfx netip.Prefix) (val V, exists bool) { + if !pfx.IsValid() { + return val, exists + } + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + return n.Get(pfx) +} + +// DeletePersist is similar to Delete but does not modify the receiver. +// +// It performs a copy-on-write delete operation, cloning all nodes touched during +// deletion and returning a new _TABLE_TYPE reflecting the change. +// +// If the prefix is invalid or doesn't exist, the original table is +// returned unchanged. +// +// If the payload type V contains pointers or requires deep copying, +// it must implement the Clone method for correct cloning. +// +// Due to cloning overhead this is significantly slower than Delete, +// typically taking μsec instead of nsec. +func (t *_TABLE_TYPE[V]) DeletePersist(pfx netip.Prefix) *_TABLE_TYPE[V] { + if !pfx.IsValid() { + return t + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + // Preflight check: avoid cloning if prefix doesn't exist + n := t.rootNodeByVersion(is4) + if _, found := n.Get(pfx); !found { + return t + } + + // share size counters; root nodes cloned selectively. + pt := &_TABLE_TYPE[V]{ + size4: t.size4, + size6: t.size6, + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // Clone root node corresponding to the IP version, for copy-on-write. + if is4 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + pt.root6 = t.root6 + n = &pt.root4 + } else { + pt.root4 = t.root4 + pt.root6 = *t.root6.CloneFlat(cloneFn) + n = &pt.root6 + } + + if exists := n.DeletePersist(cloneFn, pfx); exists { + pt.sizeUpdate(is4, -1) + } + + return pt +} + +// ModifyPersist is similar to Modify but the receiver isn't modified and +// a new *_TABLE_TYPE is returned. +func (t *_TABLE_TYPE[V]) ModifyPersist(pfx netip.Prefix, cb func(_ V, ok bool) (_ V, del bool)) *_TABLE_TYPE[V] { + if !pfx.IsValid() { + return t + } + + // make a cheap test in front of expensive operation + oldVal, ok := t.Get(pfx) + val := oldVal + + // to clone or not to clone ... + cloneFn := value.CloneFnFactory[V]() + if cloneFn != nil && ok { + val = cloneFn(oldVal) + } + + newVal, del := cb(val, ok) + + switch { + case !ok && del: // no-op + return t + + case !ok && !del: // insert + return t.InsertPersist(pfx, newVal) + + case ok && !del: // update + return t.InsertPersist(pfx, newVal) + + case ok && del: // delete + return t.DeletePersist(pfx) + } + + panic("unreachable") +} + +// Supernets returns an iterator over all supernet routes that cover the given prefix pfx. +// +// The traversal searches both exact-length and shorter (less specific) prefixes that +// include pfx. Starting from the most specific position in the trie, +// it walks upward through parent nodes and yields any matching entries found at each level. +// +// The iteration order is reverse-CIDR: from longest prefix match (LPM) towards +// least-specific routes. +// +// This can be used to enumerate all covering supernet routes in routing-based +// policy engines, diagnostics tools, or fallback resolution logic. +// +// Example: +// +// for supernet, val := range table.Supernets(netip.MustParsePrefix("192.0.2.128/25")) { +// fmt.Println("Covered by:", supernet, "->", val) +// } +// +// The iteration can be stopped early by breaking from the range loop. +// Returns an empty iterator if the prefix is invalid. +func (t *_TABLE_TYPE[V]) Supernets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if !pfx.IsValid() { + return + } + + // canonicalize the prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + n.Supernets(pfx, yield) + } +} + +// Subnets returns an iterator over all subnets of the given prefix +// in natural CIDR sort order. This includes prefixes of the same length +// (exact match) and longer (more specific) prefixes that are contained +// within the given prefix. +// +// Example: +// +// for sub, val := range table.Subnets(netip.MustParsePrefix("10.0.0.0/8")) { +// fmt.Println("Covered:", sub, "->", val) +// } +// +// The iteration can be stopped early by breaking from the range loop. +// Returns an empty iterator if the prefix is invalid. +func (t *_TABLE_TYPE[V]) Subnets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if !pfx.IsValid() { + return + } + + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + n.Subnets(pfx, yield) + } +} + +// OverlapsPrefix reports whether any prefix in the routing table overlaps with +// the given prefix. Two prefixes overlap if they share any IP addresses. +// +// The check is bidirectional: it returns true if the input prefix is covered by an existing +// route, or if any stored route is itself contained within the input prefix. +// +// Internally, the function normalizes the prefix and descends the relevant trie branch, +// using stride-based logic to identify overlap without performing a full lookup. +// +// This is useful for containment tests, route validation, or policy checks using prefix +// semantics without retrieving exact matches. +func (t *_TABLE_TYPE[V]) OverlapsPrefix(pfx netip.Prefix) bool { + if !pfx.IsValid() { + return false + } + + // canonicalize the prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + return n.OverlapsPrefixAtDepth(pfx, 0) +} + +// Overlaps reports whether any route in the receiver table overlaps +// with a route in the other table, in either direction. +// +// The overlap check is bidirectional: it returns true if any IP prefix +// in the receiver is covered by the other table, or vice versa. +// This includes partial overlaps, exact matches, and supernet/subnet relationships. +// +// Both IPv4 and IPv6 route trees are compared independently. If either +// tree has overlapping routes, the function returns true. +// +// This is useful for conflict detection, policy enforcement, +// or validating mutually exclusive routing domains. +func (t *_TABLE_TYPE[V]) Overlaps(o *_TABLE_TYPE[V]) bool { + return t.Overlaps4(o) || t.Overlaps6(o) +} + +// Overlaps4 is like [_TABLE_TYPE.Overlaps] but for the v4 routing table only. +func (t *_TABLE_TYPE[V]) Overlaps4(o *_TABLE_TYPE[V]) bool { + if t.size4 == 0 || o.size4 == 0 { + return false + } + return t.root4.Overlaps(&o.root4, 0) +} + +// Overlaps6 is like [_TABLE_TYPE.Overlaps] but for the v6 routing table only. +func (t *_TABLE_TYPE[V]) Overlaps6(o *_TABLE_TYPE[V]) bool { + if t.size6 == 0 || o.size6 == 0 { + return false + } + return t.root6.Overlaps(&o.root6, 0) +} + +// Union merges another routing table into the receiver table, modifying it in-place. +// +// All prefixes and values from the other table (o) are inserted into the receiver. +// If a duplicate prefix exists in both tables, the value from o replaces the existing entry. +// This duplicate is shallow-copied by default, but if the value type V implements the +// Clone method, the value is deeply cloned before insertion. See also _TABLE_TYPE.Clone. +func (t *_TABLE_TYPE[V]) Union(o *_TABLE_TYPE[V]) { + // panics on nil receiver + _ = t.size4 + + // panics on nil argument + if o.size4 == 0 && o.size6 == 0 { + return + } + // t is unchanged + if o == t { + return + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + dup4 := t.root4.UnionRec(cloneFn, &o.root4, 0) + dup6 := t.root6.UnionRec(cloneFn, &o.root6, 0) + + t.size4 += o.size4 - dup4 + t.size6 += o.size6 - dup6 +} + +// UnionPersist is similar to [Union] but the receiver isn't modified. +// +// All nodes touched during union are cloned and a new *_TABLE_TYPE is returned. +// If o is empty, no nodes are touched and the receiver may be +// returned unchanged. +func (t *_TABLE_TYPE[V]) UnionPersist(o *_TABLE_TYPE[V]) *_TABLE_TYPE[V] { + // panics on nil receiver + _ = t.size4 + + // panics on nil argument + if o.size4 == 0 && o.size6 == 0 { + return t + } + if o == t { + return t + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // new _TABLE_TYPE with root nodes just copied. + pt := &_TABLE_TYPE[V]{ + root4: t.root4, + root6: t.root6, + // + size4: t.size4, + size6: t.size6, + } + + // only clone the root node if there is something to union + if o.size4 != 0 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + } + if o.size6 != 0 { + pt.root6 = *t.root6.CloneFlat(cloneFn) + } + + dup4 := pt.root4.UnionRecPersist(cloneFn, &o.root4, 0) + dup6 := pt.root6.UnionRecPersist(cloneFn, &o.root6, 0) + + pt.size4 += o.size4 - dup4 + pt.size6 += o.size6 - dup6 + + return pt +} + +// Equal checks whether two tables are structurally and semantically equal. +// It ensures both trees (IPv4-based and IPv6-based) have the same sizes and +// recursively compares their root nodes. +// +// If V implements an `Equal(V) bool` method, its custom equality logic is used. +// Otherwise, values are compared directly using the == operator. +// +// Note: If V implements `Equal(V) bool` with a pointer receiver, the Equal +// method should handle nil receivers gracefully. +// +// ATTENTION: If V is not comparable at runtime (such as a slice or map without an `Equal` +// method), a runtime panic will occur. +func (t *_TABLE_TYPE[V]) Equal(o *_TABLE_TYPE[V]) bool { + if t.size4 != o.size4 || t.size6 != o.size6 { + return false + } + if o == t { + return true + } + + return t.root4.EqualRec(&o.root4) && t.root6.EqualRec(&o.root6) +} + +// Clone returns a copy of the routing table. +// The payload of type V is shallow copied by default. To enable deep copying, +// implement the following method on your value type: +// +// Clone() V +// +// Example: +// +// type MyValue struct { Data []byte } +// func (v MyValue) Clone() MyValue { +// return MyValue{Data: slices.Clone(v.Data)} +// } +// +// The bart package will automatically detect and use this method via Go's +// structural typing. +// +// Note: If V implements Clone() V with a pointer receiver, the Clone +// method should handle nil receivers gracefully. +func (t *_TABLE_TYPE[V]) Clone() *_TABLE_TYPE[V] { + c := new(_TABLE_TYPE[V]) + + cloneFn := value.CloneFnFactory[V]() + + c.root4 = *t.root4.CloneRec(cloneFn) + c.root6 = *t.root6.CloneRec(cloneFn) + + c.size4 = t.size4 + c.size6 = t.size6 + + return c +} + +// Size returns the prefix count. +func (t *_TABLE_TYPE[V]) Size() int { + return t.size4 + t.size6 +} + +// Size4 returns the IPv4 prefix count. +func (t *_TABLE_TYPE[V]) Size4() int { + return t.size4 +} + +// Size6 returns the IPv6 prefix count. +func (t *_TABLE_TYPE[V]) Size6() int { + return t.size6 +} + +// All returns an iterator over all prefix–value pairs in the table. +// +// The iteration order is unspecified and may vary between calls; for a stable order, +// use [_TABLE_TYPE.AllSorted]. +// +// IMPORTANT: Modifying the table during iteration is not allowed, +// as this would interfere with the internal traversal and may corrupt or +// prematurely terminate the iteration. +func (t *_TABLE_TYPE[V]) All() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRec(stridePath{}, 0, true, yield) && t.root6.AllRec(stridePath{}, 0, false, yield) + } +} + +// All4 is like [_TABLE_TYPE.All] but only for the v4 routing table. +func (t *_TABLE_TYPE[V]) All4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRec(stridePath{}, 0, true, yield) + } +} + +// All6 is like [_TABLE_TYPE.All] but only for the v6 routing table. +func (t *_TABLE_TYPE[V]) All6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root6.AllRec(stridePath{}, 0, false, yield) + } +} + +// AllSorted is like [_TABLE_TYPE.All] but the iteration is ordered in canonical +// CIDR prefix sort order. +func (t *_TABLE_TYPE[V]) AllSorted() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRecSorted(stridePath{}, 0, true, yield) && + t.root6.AllRecSorted(stridePath{}, 0, false, yield) + } +} + +// AllSorted4 is like [_TABLE_TYPE.AllSorted] but only for the v4 routing table. +func (t *_TABLE_TYPE[V]) AllSorted4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRecSorted(stridePath{}, 0, true, yield) + } +} + +// AllSorted6 is like [_TABLE_TYPE.AllSorted] but only for the v6 routing table. +func (t *_TABLE_TYPE[V]) AllSorted6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root6.AllRecSorted(stridePath{}, 0, false, yield) + } +} + +// Fprint writes a hierarchical tree diagram of the ordered CIDRs +// with default formatted payload V to w. +// +// The order from top to bottom is in ascending order of the prefix address +// and the subtree structure is determined by the CIDRs coverage. +// +// ▼ +// ├─ 10.0.0.0/8 (V) +// │ ├─ 10.0.0.0/24 (V) +// │ └─ 10.0.1.0/24 (V) +// ├─ 127.0.0.0/8 (V) +// │ └─ 127.0.0.1/32 (V) +// ├─ 169.254.0.0/16 (V) +// ├─ 172.16.0.0/12 (V) +// └─ 192.168.0.0/16 (V) +// └─ 192.168.1.0/24 (V) +// ▼ +// └─ ::/0 (V) +// ├─ ::1/128 (V) +// ├─ 2000::/3 (V) +// │ └─ 2001:db8::/32 (V) +// └─ fe80::/10 (V) +func (t *_TABLE_TYPE[V]) Fprint(w io.Writer) error { + if w == nil && t != nil { + return fmt.Errorf("nil writer") + } + + // v4 + if err := t.fprint(w, true); err != nil { + return err + } + + // v6 + if err := t.fprint(w, false); err != nil { + return err + } + + return nil +} + +// fprint is the version dependent adapter to fprintRec. +func (t *_TABLE_TYPE[V]) fprint(w io.Writer, is4 bool) error { + n := t.rootNodeByVersion(is4) + if n.IsEmpty() { + return nil + } + + if _, err := fmt.Fprint(w, "▼\n"); err != nil { + return err + } + + startParent := nodes.TrieItem[V]{ + Node: nil, + Idx: 0, + Path: stridePath{}, + Is4: is4, + } + + return n.FprintRec(w, startParent, "") +} + +// MarshalText implements the [encoding.TextMarshaler] interface, +// just a wrapper for [_TABLE_TYPE.Fprint]. +func (t *_TABLE_TYPE[V]) MarshalText() ([]byte, error) { + w := new(bytes.Buffer) + if err := t.Fprint(w); err != nil { + return nil, err + } + + return w.Bytes(), nil +} + +// MarshalJSON dumps the table into two sorted lists: for ipv4 and ipv6. +// Every root and subnet is an array, not a map, because the order matters. +func (t *_TABLE_TYPE[V]) MarshalJSON() ([]byte, error) { + result := struct { + Ipv4 []DumpListNode[V] `json:"ipv4,omitempty"` + Ipv6 []DumpListNode[V] `json:"ipv6,omitempty"` + }{ + Ipv4: t.DumpList4(), + Ipv6: t.DumpList6(), + } + + buf, err := json.Marshal(result) + if err != nil { + return nil, err + } + + return buf, nil +} + +// DumpList4 dumps the ipv4 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build the text or JSON serialization. +func (t *_TABLE_TYPE[V]) DumpList4() []DumpListNode[V] { + return t.dumpListRec(&t.root4, 0, stridePath{}, 0, true) +} + +// DumpList6 dumps the ipv6 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build custom JSON representation. +func (t *_TABLE_TYPE[V]) DumpList6() []DumpListNode[V] { + return t.dumpListRec(&t.root6, 0, stridePath{}, 0, false) +} + +// dumpListRec, build the data structure rec-descent with the help of directItemsRec. +// anyNode is nodes.BartNode, nodes.FastNode or nodes.LiteNode +func (t *_TABLE_TYPE[V]) dumpListRec(anyNode any, parentIdx uint8, path stridePath, depth int, is4 bool) []DumpListNode[V] { + // recursion stop condition + if anyNode == nil { + return nil + } + + // the same method is generated for all table types, therefore + // type assert to the smallest needed interface. + // The panic on wrong type assertion is by intention, MUST NOT happen + n := anyNode.(interface { + DirectItemsRec(uint8, stridePath, int, bool) []nodes.TrieItem[V] + }) + + directItems := n.DirectItemsRec(parentIdx, path, depth, is4) + + // sort the items by prefix + slices.SortFunc(directItems, func(a, b nodes.TrieItem[V]) int { + return nodes.CmpPrefix(a.Cidr, b.Cidr) + }) + + dumpNodes := make([]DumpListNode[V], 0, len(directItems)) + + for _, item := range directItems { + dumpNodes = append(dumpNodes, DumpListNode[V]{ + CIDR: item.Cidr, + Value: item.Val, + // build it rec-descent, item.Node is also from type any + Subnets: t.dumpListRec(item.Node, item.Idx, item.Path, item.Depth, is4), + }) + } + + return dumpNodes +} + +// dumpString is just a wrapper for dump. +func (t *_TABLE_TYPE[V]) dumpString() string { + w := new(strings.Builder) + t.dump(w) + + return w.String() +} + +// dump the table structure and all the nodes to w. +func (t *_TABLE_TYPE[V]) dump(w io.Writer) { + if t.size4 > 0 { + stats := t.root4.StatsRec() + fmt.Fprintln(w) + fmt.Fprintf(w, "### IPv4: size(%d), subnodes(%d), prefixes(%d), leaves(%d), fringes(%d)", + t.size4, stats.SubNodes, stats.Prefixes, stats.Leaves, stats.Fringes) + + t.root4.DumpRec(w, stridePath{}, 0, true) + } + + if t.size6 > 0 { + stats := t.root6.StatsRec() + fmt.Fprintln(w) + fmt.Fprintf(w, "### IPv6: size(%d), subnodes(%d), prefixes(%d), leaves(%d), fringes(%d)", + t.size6, stats.SubNodes, stats.Prefixes, stats.Leaves, stats.Fringes) + + t.root6.DumpRec(w, stridePath{}, 0, false) + } +} diff --git a/vendor/github.com/gaissmai/bart/commontests_tmpl.go b/vendor/github.com/gaissmai/bart/commontests_tmpl.go new file mode 100644 index 0000000..ef73ab0 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/commontests_tmpl.go @@ -0,0 +1,2299 @@ +//go:build generate + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +//go:generate ./scripts/generate-table-tests.sh + +package bart + +// ### GENERATE DELETE START ### + +// stub code for generator types and methods +// useful for gopls during development, deleted during go generate + +import ( + "encoding/json" + "io" + "iter" + "math/rand/v2" + "net/netip" + "slices" + "strings" + "testing" + + "github.com/gaissmai/bart/internal/nodes" + "github.com/gaissmai/bart/internal/tests/golden" + "github.com/gaissmai/bart/internal/tests/random" +) + +type ( + _NODE_TYPE[V any] struct{} + + _TABLE_TYPE[V any] struct { + root4 _NODE_TYPE[V] + root6 _NODE_TYPE[V] + } +) + +func (*_NODE_TYPE[V]) StatsRec() (_ nodes.StatsT) { return } + +func (*_TABLE_TYPE[V]) rootNodeByVersion(bool) (_ *_NODE_TYPE[V]) { return } +func (*_TABLE_TYPE[V]) sizeUpdate(bool, int) { return } +func (*_TABLE_TYPE[V]) dump(io.Writer) { return } +func (*_TABLE_TYPE[V]) dumpString() (_ string) { return } +func (*_TABLE_TYPE[V]) fprint(io.Writer, bool) (_ error) { return } +func (*_TABLE_TYPE[V]) Fprint(io.Writer) (_ error) { return } +func (*_TABLE_TYPE[V]) Size() (_ int) { return } +func (*_TABLE_TYPE[V]) Size4() (_ int) { return } +func (*_TABLE_TYPE[V]) Size6() (_ int) { return } +func (*_TABLE_TYPE[V]) Insert(netip.Prefix, V) { return } +func (*_TABLE_TYPE[V]) Get(netip.Prefix) (_ V, _ bool) { return } +func (*_TABLE_TYPE[V]) Delete(netip.Prefix) { return } +func (*_TABLE_TYPE[V]) Modify(netip.Prefix, func(V, bool) (V, bool)) { return } +func (*_TABLE_TYPE[V]) Clone() (_ *_TABLE_TYPE[V]) { return } +func (*_TABLE_TYPE[V]) Union(*_TABLE_TYPE[V]) { return } +func (*_TABLE_TYPE[V]) Equal(*_TABLE_TYPE[V]) (_ bool) { return } +func (*_TABLE_TYPE[V]) OverlapsPrefix(netip.Prefix) (_ bool) { return } +func (*_TABLE_TYPE[V]) Overlaps(*_TABLE_TYPE[V]) (_ bool) { return } +func (*_TABLE_TYPE[V]) Overlaps4(*_TABLE_TYPE[V]) (_ bool) { return } +func (*_TABLE_TYPE[V]) Overlaps6(*_TABLE_TYPE[V]) (_ bool) { return } +func (*_TABLE_TYPE[V]) Contains(netip.Addr) (_ bool) { return } +func (*_TABLE_TYPE[V]) Lookup(netip.Addr) (_ V, _ bool) { return } +func (*_TABLE_TYPE[V]) LookupPrefix(netip.Prefix) (_ V, _ bool) { return } +func (*_TABLE_TYPE[V]) LookupPrefixLPM(netip.Prefix) (_ netip.Prefix, _ V, _ bool) { return } + +func (*_TABLE_TYPE[V]) InsertPersist(netip.Prefix, V) (_ *_TABLE_TYPE[V]) { return } +func (*_TABLE_TYPE[V]) DeletePersist(netip.Prefix) (_ *_TABLE_TYPE[V]) { return } +func (*_TABLE_TYPE[V]) UnionPersist(*_TABLE_TYPE[V]) (_ *_TABLE_TYPE[V]) { return } +func (*_TABLE_TYPE[V]) ModifyPersist(netip.Prefix, func(V, bool) (V, bool)) (_ *_TABLE_TYPE[V]) { + return +} +func (*_TABLE_TYPE[V]) MarshalText() (_ []byte, _ error) { return } +func (*_TABLE_TYPE[V]) MarshalJSON() (_ []byte, _ error) { return } +func (*_TABLE_TYPE[V]) DumpList4() (_ []DumpListNode[V]) { return } +func (*_TABLE_TYPE[V]) DumpList6() (_ []DumpListNode[V]) { return } + +func (*_TABLE_TYPE[V]) All() (_ iter.Seq2[netip.Prefix, V]) { return } +func (*_TABLE_TYPE[V]) All4() (_ iter.Seq2[netip.Prefix, V]) { return } +func (*_TABLE_TYPE[V]) All6() (_ iter.Seq2[netip.Prefix, V]) { return } + +func (*_TABLE_TYPE[V]) AllSorted() (_ iter.Seq2[netip.Prefix, V]) { return } +func (*_TABLE_TYPE[V]) AllSorted4() (_ iter.Seq2[netip.Prefix, V]) { return } +func (*_TABLE_TYPE[V]) AllSorted6() (_ iter.Seq2[netip.Prefix, V]) { return } + +func (*_TABLE_TYPE[V]) Subnets(netip.Prefix) (_ iter.Seq2[netip.Prefix, V]) { return } +func (*_TABLE_TYPE[V]) Supernets(netip.Prefix) (_ iter.Seq2[netip.Prefix, V]) { return } + +// ### GENERATE DELETE END ### + +// ############ tests ################################ + +// flatSorted, just a helper to compare with golden table. +func (t *_TABLE_TYPE[V]) flatSorted() golden.Table[V] { + var flat golden.Table[V] + + for p, v := range t.AllSorted() { + flat = append(flat, golden.TableItem[V]{Pfx: p, Val: v}) + } + + return flat +} + +func TestTableNilReceiver__TABLE_TYPE(t *testing.T) { + t.Parallel() + + var tbl1 *_TABLE_TYPE[any] = nil + + ip4 := mpa("127.0.0.1") + ip6 := mpa("::1") + + pfx4 := mpp("127.0.0.0/8") + pfx6 := mpp("::1/128") + + tbl2 := new(_TABLE_TYPE[any]) + tbl2.Insert(pfx4, true) + tbl2.Insert(pfx6, true) + + t.Run("mustPanicNilReceiver", func(t *testing.T) { + t.Parallel() + + mustPanic(t, "Size", func() { tbl1.Size() }) + mustPanic(t, "Size4", func() { tbl1.Size4() }) + mustPanic(t, "Size6", func() { tbl1.Size6() }) + + mustPanic(t, "Get", func() { tbl1.Get(pfx4) }) + mustPanic(t, "Insert", func() { tbl1.Insert(pfx4, nil) }) + mustPanic(t, "InsertPersist", func() { tbl1.InsertPersist(pfx4, nil) }) + mustPanic(t, "Delete", func() { tbl1.Delete(pfx4) }) + mustPanic(t, "DeletePersist", func() { tbl1.DeletePersist(pfx4) }) + mustPanic(t, "Modify", func() { tbl1.Modify(pfx4, nil) }) + mustPanic(t, "ModifyPersist", func() { tbl1.ModifyPersist(pfx4, nil) }) + mustPanic(t, "Contains", func() { tbl1.Contains(ip4) }) + mustPanic(t, "Lookup", func() { tbl1.Lookup(ip6) }) + mustPanic(t, "LookupPrefix", func() { tbl1.LookupPrefix(pfx4) }) + mustPanic(t, "LookupPrefixLPM", func() { tbl1.LookupPrefixLPM(pfx4) }) + mustPanic(t, "Clone", func() { tbl1.Clone() }) + mustPanic(t, "Union", func() { tbl1.Union(tbl2) }) + mustPanic(t, "UnionPersist", func() { tbl1.UnionPersist(tbl2) }) + mustPanic(t, "Overlaps", func() { tbl1.Overlaps(tbl2) }) + mustPanic(t, "Overlaps4", func() { tbl1.Overlaps4(tbl2) }) + mustPanic(t, "Overlaps6", func() { tbl1.Overlaps6(tbl2) }) + mustPanic(t, "OverlapsPrefix", func() { tbl1.OverlapsPrefix(pfx4) }) + mustPanic(t, "OverlapsPrefix", func() { tbl1.OverlapsPrefix(pfx6) }) + mustPanic(t, "Equal", func() { tbl1.Equal(tbl2) }) + mustPanic(t, "DumpList4", func() { tbl1.DumpList4() }) + mustPanic(t, "DumpList6", func() { tbl1.DumpList6() }) + mustPanic(t, "Fprint", func() { tbl1.Fprint(nil) }) + mustPanic(t, "MarshalJSON", func() { _, _ = tbl1.MarshalJSON() }) + mustPanic(t, "MarshalText", func() { _, _ = tbl1.MarshalText() }) + + mustPanicRangeOverFunc[any](t, "All", tbl1.All) + mustPanicRangeOverFunc[any](t, "All4", tbl1.All4) + mustPanicRangeOverFunc[any](t, "All6", tbl1.All6) + mustPanicRangeOverFunc[any](t, "AllSorted", tbl1.AllSorted) + mustPanicRangeOverFunc[any](t, "AllSorted4", tbl1.AllSorted4) + mustPanicRangeOverFunc[any](t, "AllSorted6", tbl1.AllSorted6) + mustPanicRangeOverFunc[any](t, "Subnets", tbl1.Subnets) + mustPanicRangeOverFunc[any](t, "Supernets", tbl1.Supernets) + }) +} + +func TestTableNilArguments__TABLE_TYPE(t *testing.T) { + t.Parallel() + + t.Run("mustPanicNilArgs", func(t *testing.T) { + t.Parallel() + tbl := new(_TABLE_TYPE[bool]) + + tbl.Insert(mpp("127.0.0.1/32"), true) + tbl.Insert(mpp("::1/128"), true) + + mustPanic(t, "Union(nil)", func() { tbl.Union(nil) }) + mustPanic(t, "UnionPersist(nil)", func() { tbl.UnionPersist(nil) }) + mustPanic(t, "Overlaps(nil)", func() { tbl.Overlaps(nil) }) + mustPanic(t, "Overlaps4(nil)", func() { tbl.Overlaps4(nil) }) + mustPanic(t, "Overlaps6(nil)", func() { tbl.Overlaps6(nil) }) + mustPanic(t, "Equal(nil)", func() { tbl.Equal(nil) }) + }) +} + +func TestTableInvalid__TABLE_TYPE(t *testing.T) { + t.Parallel() + + tbl1 := new(_TABLE_TYPE[any]) + tbl2 := new(_TABLE_TYPE[any]) + + var zeroIP netip.Addr + var zeroPfx netip.Prefix + + noPanic(t, "All", func() { tbl1.All() }) + noPanic(t, "All4", func() { tbl1.All4() }) + noPanic(t, "All6", func() { tbl1.All6() }) + noPanic(t, "AllSorted", func() { tbl1.AllSorted() }) + noPanic(t, "AllSorted4", func() { tbl1.AllSorted4() }) + noPanic(t, "AllSorted6", func() { tbl1.AllSorted6() }) + noPanic(t, "Clone", func() { tbl1.Clone() }) + noPanic(t, "Contains", func() { tbl1.Contains(zeroIP) }) + noPanic(t, "Delete", func() { tbl1.Delete(zeroPfx) }) + noPanic(t, "DeletePersist", func() { tbl1.DeletePersist(zeroPfx) }) + noPanic(t, "DumpList4", func() { tbl1.DumpList4() }) + noPanic(t, "DumpList6", func() { tbl1.DumpList6() }) + noPanic(t, "Equal", func() { tbl1.Equal(tbl2) }) + noPanic(t, "Fprint", func() { tbl1.Fprint(nil) }) + noPanic(t, "Get", func() { tbl1.Get(zeroPfx) }) + noPanic(t, "Insert", func() { tbl1.Insert(zeroPfx, nil) }) + noPanic(t, "InsertPersist", func() { tbl1.InsertPersist(zeroPfx, nil) }) + noPanic(t, "Lookup", func() { tbl1.Lookup(zeroIP) }) + noPanic(t, "LookupPrefix", func() { tbl1.LookupPrefix(zeroPfx) }) + noPanic(t, "LookupPrefixLPM", func() { tbl1.LookupPrefixLPM(zeroPfx) }) + noPanic(t, "MarshalJSON", func() { _, _ = tbl1.MarshalJSON() }) + noPanic(t, "MarshalText", func() { _, _ = tbl1.MarshalText() }) + noPanic(t, "Modify", func() { tbl1.Modify(zeroPfx, nil) }) + noPanic(t, "ModifyPersist", func() { tbl1.ModifyPersist(zeroPfx, nil) }) + noPanic(t, "Overlaps", func() { tbl1.Overlaps(tbl2) }) + noPanic(t, "Overlaps4", func() { tbl1.Overlaps4(tbl2) }) + noPanic(t, "Overlaps6", func() { tbl1.Overlaps6(tbl2) }) + noPanic(t, "OverlapsPrefix", func() { tbl1.OverlapsPrefix(zeroPfx) }) + noPanic(t, "Size", func() { tbl1.Size() }) + noPanic(t, "Size4", func() { tbl1.Size4() }) + noPanic(t, "Size6", func() { tbl1.Size6() }) + noPanic(t, "Subnets", func() { tbl1.Subnets(zeroPfx) }) + noPanic(t, "Supernets", func() { tbl1.Supernets(zeroPfx) }) + noPanic(t, "Union", func() { tbl1.Union(tbl2) }) + noPanic(t, "UnionPersist", func() { tbl1.UnionPersist(tbl2) }) +} + +func TestTableContainsCompare__TABLE_TYPE(t *testing.T) { + // Create large route tables repeatedly, and compare Table's + // behavior to a naive and slow but correct implementation. + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[int]) + tbl := new(_TABLE_TYPE[int]) + + for i, p := range pfxs { + gold.Insert(p, i) + tbl.Insert(p, i) + } + + for range n { + ip := random.IP(prng) + + _, goldOK := gold.Lookup(ip) + tblOK := tbl.Contains(ip) + + if goldOK != tblOK { + t.Fatalf("Contains(%q) = %v, want %v", ip, tblOK, goldOK) + } + } +} + +func TestTableLookupCompare__TABLE_TYPE(t *testing.T) { + // Create large route tables repeatedly, and compare Table's + // behavior to a naive and slow but correct implementation. + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[int]) + tbl := new(_TABLE_TYPE[int]) + + for i, pfx := range pfxs { + gold.Insert(pfx, i) + tbl.Insert(pfx, i) + } + + for range n { + ip := random.IP(prng) + + goldVal, goldOK := gold.Lookup(ip) + tblVal, tblOK := tbl.Lookup(ip) + + if goldOK != tblOK { + t.Fatalf("Lookup(%q) = (_, %v), want %v", ip, tblOK, goldOK) + } + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[int]); !isLite { + if goldVal != tblVal { + t.Fatalf("Lookup(%q) = (%v, %v), want (%v, %v)", ip, tblVal, tblOK, goldVal, goldOK) + } + } + } +} + +func TestTableLookupPrefixUnmasked__TABLE_TYPE(t *testing.T) { + // test that the pfx must not be masked on input for LookupPrefix + t.Parallel() + + tbl := new(_TABLE_TYPE[any]) + tbl.Insert(mpp("10.20.30.0/24"), nil) + tbl.Insert(mpp("2001:db8::/32"), nil) + + // not normalized pfxs + tests := []struct { + probe netip.Prefix + wantLPM netip.Prefix + wantOk bool + }{ + { + probe: netip.MustParsePrefix("10.20.30.40/0"), + wantLPM: netip.Prefix{}, + wantOk: false, + }, + { + probe: netip.MustParsePrefix("10.20.30.40/23"), + wantLPM: netip.Prefix{}, + wantOk: false, + }, + { + probe: netip.MustParsePrefix("10.20.30.40/24"), + wantLPM: mpp("10.20.30.0/24"), + wantOk: true, + }, + { + probe: netip.MustParsePrefix("10.20.30.40/25"), + wantLPM: mpp("10.20.30.0/24"), + wantOk: true, + }, + { + probe: netip.MustParsePrefix("10.20.30.40/32"), + wantLPM: mpp("10.20.30.0/24"), + wantOk: true, + }, + // IPv6 counterparts + { + probe: netip.MustParsePrefix("2001:db8::1/0"), + wantLPM: netip.Prefix{}, + wantOk: false, + }, + { + probe: netip.MustParsePrefix("2001:db8::1/31"), + wantLPM: netip.Prefix{}, + wantOk: false, + }, + { + probe: netip.MustParsePrefix("2001:db8::1/32"), + wantLPM: mpp("2001:db8::/32"), + wantOk: true, + }, + { + probe: netip.MustParsePrefix("2001:db8::1/64"), + wantLPM: mpp("2001:db8::/32"), + wantOk: true, + }, + } + + for _, tc := range tests { + _, got := tbl.LookupPrefix(tc.probe) + if got != tc.wantOk { + t.Errorf("LookupPrefix non canonical prefix (%s), got: %v, want: %v", tc.probe, got, tc.wantOk) + } + + lpm, _, got := tbl.LookupPrefixLPM(tc.probe) + if got != tc.wantOk { + t.Errorf("LookupPrefixLPM non canonical prefix (%s), got: %v, want: %v", tc.probe, got, tc.wantOk) + } + if lpm != tc.wantLPM { + t.Errorf("LookupPrefixLPM non canonical prefix (%s), got: %v, want: %v", tc.probe, lpm, tc.wantLPM) + } + } +} + +func TestTableLookupPrefixCompare__TABLE_TYPE(t *testing.T) { + // Create large route tables repeatedly, and compare Table's + // behavior to a naive and slow but correct implementation. + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[int]) + tbl := new(_TABLE_TYPE[int]) + for i, pfx := range pfxs { + gold.Insert(pfx, i) + tbl.Insert(pfx, i) + } + + for range n { + pfx := random.Prefix(prng) + + goldVal, goldOK := gold.LookupPrefix(pfx) + tblVal, tblOK := tbl.LookupPrefix(pfx) + + if goldOK != tblOK { + t.Fatalf("LookupPrefix(%q) = (_, %v), want (_, %v)", pfx, tblOK, goldOK) + } + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[int]); !isLite { + if goldVal != tblVal { + t.Fatalf("LookupPrefix(%q) = (%v, %v), want (%v, %v)", pfx, tblVal, tblOK, goldVal, goldOK) + } + } + } +} + +func TestTableLookupPrefixLPMCompare__TABLE_TYPE(t *testing.T) { + // Create large route tables repeatedly, and compare Table's + // behavior to a naive and slow but correct implementation. + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[int]) + tbl := new(_TABLE_TYPE[int]) + for i, pfx := range pfxs { + gold.Insert(pfx, i) + tbl.Insert(pfx, i) + } + + for range n { + pfx := random.Prefix(prng) + + goldLPM, goldVal, goldOK := gold.LookupPrefixLPM(pfx) + tblLPM, tblVal, tblOK := tbl.LookupPrefixLPM(pfx) + + if goldOK != tblOK { + t.Fatalf("LookupPrefixLPM(%q) = (_, _, %v), want (_, _, %v)", pfx, tblOK, goldOK) + } + + if goldLPM != tblLPM { + t.Fatalf("LookupPrefixLPM(%q) = ( %v, _, _), want ( %v, _, _)", pfx, tblLPM, goldLPM) + } + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[int]); !isLite { + if goldVal != tblVal { + t.Fatalf("LookupPrefixLPM(%q) = (_, %v, _), want (_, %v, _)", pfx, tblVal, goldVal) + } + } + } +} + +func TestTableInsertShuffled__TABLE_TYPE(t *testing.T) { + // The order in which you insert prefixes into a route table + // should not matter, as long as you're inserting the same set of + // routes. + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + for range 10 { + pfxs2 := slices.Clone(pfxs) + prng.Shuffle(len(pfxs2), func(i, j int) { pfxs2[i], pfxs2[j] = pfxs2[j], pfxs2[i] }) + + tbl1 := new(_TABLE_TYPE[string]) + tbl2 := new(_TABLE_TYPE[string]) + + for _, pfx := range pfxs { + tbl1.Insert(pfx, pfx.String()) + tbl1.Insert(pfx, pfx.String()) // idempotent + } + for _, pfx := range pfxs2 { + tbl2.Insert(pfx, pfx.String()) // idempotent + } + + if tbl1.dumpString() != tbl2.dumpString() { + t.Fatal("tbl1 and tbl2 have different dumpString representation") + } + if !tbl1.Equal(tbl2) { + t.Fatal("expected Equal") + } + } +} + +func TestTableInsertPersistShuffled__TABLE_TYPE(t *testing.T) { + // The order in which you insert prefixes into a route table + // should not matter, as long as you're inserting the same set of + // routes. + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + for range 10 { + pfxs2 := slices.Clone(pfxs) + prng.Shuffle(len(pfxs2), func(i, j int) { pfxs2[i], pfxs2[j] = pfxs2[j], pfxs2[i] }) + + tbl1 := new(_TABLE_TYPE[string]) + tbl2 := new(_TABLE_TYPE[string]) + + // bart1 is mutable + for _, pfx := range pfxs { + tbl1.Insert(pfx, pfx.String()) + } + + // bart2 is persistent + for _, pfx := range pfxs2 { + tbl2 = tbl2.InsertPersist(pfx, pfx.String()) + } + + if tbl1.dumpString() != tbl2.dumpString() { + t.Fatal("mutable and immutable table have different dumpString representation") + } + + if !tbl1.Equal(tbl2) { + t.Fatal("expected Equal") + } + } +} + +func TestTableDeleteCompare__TABLE_TYPE(t *testing.T) { + // Create large route tables repeatedly, delete half of their + // prefixes, and compare Table's behavior to a naive and slow but + // correct implementation. + t.Parallel() + + var ( + n = workLoadN() + prng = rand.New(rand.NewPCG(42, 42)) + numPrefixes = n // total prefixes to insert (test deletes 50% of them) + numPerFamily = numPrefixes / 2 + deleteCut = numPerFamily / 2 + probes = 3 + ) + + for range probes { + all4 := random.RealWorldPrefixes4(prng, numPerFamily) + all6 := random.RealWorldPrefixes6(prng, numPerFamily) + + pfxs := slices.Concat(all4, all6) + toDelete := slices.Concat(all4[deleteCut:], all6[deleteCut:]) + + gold := new(golden.Table[string]) + tbl := new(_TABLE_TYPE[string]) + + for _, pfx := range pfxs { + gold.Insert(pfx, pfx.String()) + tbl.Insert(pfx, pfx.String()) + } + + for _, pfx := range toDelete { + gold.Delete(pfx) + tbl.Delete(pfx) + } + + gold.Sort() + + tblFlat := tbl.flatSorted() + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[string]); isLite { + if !slices.Equal(gold.AllSorted(), tblFlat.AllSorted()) { + t.Fatal("expected Equal") + } + } else { + if !slices.Equal(*gold, tblFlat) { + t.Fatal("expected Equal") + } + } + } +} + +func TestTableDeleteShuffled__TABLE_TYPE(t *testing.T) { + // The order in which you delete prefixes from a route table + // should not matter, as long as you're deleting the same set of + // routes. + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + + var ( + numPrefixes = n // prefixes to insert (test deletes 50% of them) + numPerFamily = numPrefixes / 2 + deleteCut = numPerFamily / 2 + ) + + for range 10 { + all4 := random.RealWorldPrefixes4(prng, numPerFamily) + all6 := random.RealWorldPrefixes6(prng, numPerFamily) + + pfxs := slices.Concat(all4, all6) + toDelete := slices.Concat(all4[deleteCut:], all6[deleteCut:]) + + tbl := new(_TABLE_TYPE[string]) + + // insert + for _, pfx := range pfxs { + tbl.Insert(pfx, pfx.String()) + } + + // delete + for _, pfx := range toDelete { + tbl.Delete(pfx) + } + + pfxs2 := slices.Clone(pfxs) + toDelete2 := slices.Clone(toDelete) + prng.Shuffle(len(toDelete2), func(i, j int) { toDelete2[i], toDelete2[j] = toDelete2[j], toDelete2[i] }) + + tbl2 := new(_TABLE_TYPE[string]) + + // insert + for _, pfx := range pfxs2 { + tbl2.Insert(pfx, pfx.String()) + } + + // delete + for _, pfx := range toDelete2 { + tbl2.Delete(pfx) + } + + if !tbl.Equal(tbl2) { + t.Fatal("expect equal") + } + } +} + +func TestTableDeleteIsReverseOfInsert__TABLE_TYPE(t *testing.T) { + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + // Insert n prefixes, then delete those same prefixes in reverse + // order. Each deletion should exactly undo the internal structure + // changes that each insert did. + + tbl := new(_TABLE_TYPE[string]) + want := tbl.dumpString() + + prefixes := random.RealWorldPrefixes(prng, n) + + defer func() { + if t.Failed() { + t.Logf("the prefixes that fail the test: %v\n", prefixes) + } + }() + + for _, p := range prefixes { + tbl.Insert(p, p.String()) + } + + for i := len(prefixes) - 1; i >= 0; i-- { + tbl.Delete(prefixes[i]) + } + if got := tbl.dumpString(); got != want { + t.Fatalf("after delete, mismatch:\n\n got: %s\n\nwant: %s", got, want) + } +} + +func TestTableDeleteButOne__TABLE_TYPE(t *testing.T) { + t.Parallel() + prng := rand.New(rand.NewPCG(42, 42)) + // Insert n prefixes, then delete all but one + n := workLoadN() + + for range 10 { + + tbl := new(_TABLE_TYPE[any]) + prefixes := random.RealWorldPrefixes(prng, n) + + for _, p := range prefixes { + tbl.Insert(p, nil) + } + + // shuffle the prefixes + prng.Shuffle(n, func(i, j int) { + prefixes[i], prefixes[j] = prefixes[j], prefixes[i] + }) + + // skip the first + for i := 1; i < len(prefixes); i++ { + tbl.Delete(prefixes[i]) + } + + if size := tbl.Size(); size != 1 { + t.Fatalf("Size(), got %d, want 1", size) + } + + stats4 := tbl.root4.StatsRec() + stats6 := tbl.root6.StatsRec() + + if nodes := stats4.SubNodes + stats6.SubNodes; nodes != 1 { + t.Fatalf("delete but one, want nodes: 1, got: %d\n%s", nodes, tbl.dumpString()) + } + + sum := stats4.Prefixes + stats4.Leaves + stats4.Fringes + + stats6.Prefixes + stats6.Leaves + stats6.Fringes + + if sum != 1 { + t.Fatalf("delete but one, only one item must be left, but: %d\n%s", sum, tbl.dumpString()) + } + } +} + +func TestTableGet__TABLE_TYPE(t *testing.T) { + t.Parallel() + prng := rand.New(rand.NewPCG(42, 42)) + pfx := random.Prefix(prng) + + tests := []struct { + name string + pfx netip.Prefix + val int + }{ + { + name: "default route v4", + pfx: mpp("0.0.0.0/0"), + val: 0, + }, + { + name: "default route v6", + pfx: mpp("::/0"), + val: 0, + }, + { + name: "set v4", + pfx: mpp("1.2.3.4/32"), + val: 1234, + }, + { + name: "set v6", + pfx: mpp("2001:db8::/32"), + val: 2001, + }, + } + + tbl := new(_TABLE_TYPE[int]) + if _, ok := tbl.Get(pfx); ok { + t.Errorf("empty table: Get(%v), ok=%v, expected: %v", pfx, ok, false) + } + + for _, tt := range tests { + tbl.Insert(tt.pfx, tt.val) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + got, ok := tbl.Get(tt.pfx) + + if !ok { + t.Errorf("%s: ok=%v, expected: %v", tt.name, ok, true) + } + + if got != tt.val { + t.Errorf("%s: val=%v, expected: %v", tt.name, got, tt.val) + } + }) + } +} + +func TestTableGetCompare__TABLE_TYPE(t *testing.T) { + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[string]) + tbl := new(_TABLE_TYPE[string]) + for _, pfx := range pfxs { + gold.Insert(pfx, pfx.String()) + tbl.Insert(pfx, pfx.String()) + } + + for _, pfx := range pfxs { + goldVal, goldOK := gold.Get(pfx) + tblVal, tblOK := tbl.Get(pfx) + + if goldOK != tblOK { + t.Fatalf("Get(%q) = (_, %v), want (_, %v)", pfx, tblOK, goldOK) + } + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[string]); !isLite { + if goldVal != tblVal { + t.Fatalf("Get(%q) = (%v, %v), want (%v, %v)", pfx, tblVal, tblOK, goldVal, goldOK) + } + } + } +} + +func TestTableModifySemantics__TABLE_TYPE(t *testing.T) { + t.Parallel() + + type args struct { + pfx netip.Prefix + cb func(val int, found bool) (_ int, del bool) + } + + tests := []struct { + name string + prepare map[netip.Prefix]int // entries to pre-populate the table + args args + finalData map[netip.Prefix]int // expected table contents after the operation + }{ + { + name: "Delete existing entry", + prepare: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42, mpp("2001:db8::/32"): 4242}, + args: args{ + pfx: mpp("10.0.0.0/8"), + cb: func(val int, found bool) (_ int, del bool) { return 0, true }, + }, + finalData: map[netip.Prefix]int{mpp("2001:db8::/32"): 4242}, + }, + + { + name: "Insert new entry", + prepare: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42}, + args: args{ + pfx: mpp("2001:db8::/32"), + cb: func(val int, found bool) (_ int, del bool) { return 4242, false }, + }, + finalData: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42, mpp("2001:db8::/32"): 4242}, + }, + + { + name: "Update existing entry", + prepare: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42, mpp("2001:db8::/32"): 4242}, + args: args{ + pfx: mpp("10.0.0.0/8"), + cb: func(val int, found bool) (_ int, del bool) { return -1, false }, + }, + finalData: map[netip.Prefix]int{mpp("10.0.0.0/8"): -1, mpp("2001:db8::/32"): 4242}, + }, + + { + name: "No-op on missing entry", + prepare: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42}, + args: args{ + pfx: mpp("2001:db8::/32"), + cb: func(val int, found bool) (_ int, del bool) { return 0, true }, + }, + finalData: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42}, + }, + } + + for _, tt := range tests { + tbl := new(_TABLE_TYPE[int]) + + // Insert initial entries using Modify + for pfx, v := range tt.prepare { + tbl.Modify(pfx, func(_ int, _ bool) (_ int, del bool) { return v, false }) + } + + tbl.Modify(tt.args.pfx, tt.args.cb) + + // Check the final state of the table using Get, compares expected and actual table + got := make(map[netip.Prefix]int, len(tt.finalData)) + for pfx, val := range tbl.All() { + got[pfx] = val + } + if len(got) != len(tt.finalData) { + t.Fatalf("[%s] final table size mismatch: got %d, want %d", tt.name, len(got), len(tt.finalData)) + } + for pfx, wantVal := range tt.finalData { + gotVal, ok := got[pfx] + if !ok || gotVal != wantVal { + t.Fatalf("[%s] final table: key %v = %v (present=%v), want %v", tt.name, pfx, gotVal, ok, wantVal) + } + } + } +} + +func TestTableModifyPersistSemantics__TABLE_TYPE(t *testing.T) { + t.Parallel() + + if _, isLite := any(new(_TABLE_TYPE[any])).(*liteTable[any]); isLite { + t.Skip("liteNode has no real payload") + } + + type args struct { + pfx netip.Prefix + cb func(val int, found bool) (_ int, del bool) + } + + tests := []struct { + name string + prepare map[netip.Prefix]int // entries to pre-populate the table + args args + finalData map[netip.Prefix]int // expected table contents after the operation + }{ + { + name: "Delete existing entry", + prepare: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42, mpp("2001:db8::/32"): 4242}, + args: args{ + pfx: mpp("10.0.0.0/8"), + cb: func(val int, found bool) (_ int, del bool) { return 0, true }, + }, + finalData: map[netip.Prefix]int{mpp("2001:db8::/32"): 4242}, + }, + + { + name: "Insert new entry", + prepare: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42}, + args: args{ + pfx: mpp("2001:db8::/32"), + cb: func(val int, found bool) (_ int, del bool) { return 4242, false }, + }, + finalData: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42, mpp("2001:db8::/32"): 4242}, + }, + + { + name: "Update existing entry", + prepare: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42, mpp("2001:db8::/32"): 4242}, + args: args{ + pfx: mpp("10.0.0.0/8"), + cb: func(val int, found bool) (_ int, del bool) { return -1, false }, + }, + finalData: map[netip.Prefix]int{mpp("10.0.0.0/8"): -1, mpp("2001:db8::/32"): 4242}, + }, + + { + name: "No-op on missing entry", + prepare: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42}, + args: args{ + pfx: mpp("2001:db8::/32"), + cb: func(val int, found bool) (_ int, del bool) { return 0, true }, + }, + finalData: map[netip.Prefix]int{mpp("10.0.0.0/8"): 42}, + }, + } + + for _, tt := range tests { + tbl := new(_TABLE_TYPE[int]) + + // Insert initial entries using Modify + for pfx, v := range tt.prepare { + tbl.Modify(pfx, func(_ int, _ bool) (_ int, del bool) { return v, false }) + } + + prt := tbl.ModifyPersist(tt.args.pfx, tt.args.cb) + + // Check the final state of the table using Get, compares expected and actual table + for pfx, wantVal := range tt.finalData { + gotVal, ok := prt.Get(pfx) + if !ok || gotVal != wantVal { + t.Errorf("[%s] final table: key %v = %v (ok=%v), want %v (ok=true)", tt.name, pfx, gotVal, ok, wantVal) + } + } + + // Ensure there are no unexpected entries + for pfx := range tt.prepare { + if _, expect := tt.finalData[pfx]; !expect { + if _, ok := prt.Get(pfx); ok { + t.Errorf("[%s] final table: key %v should not be present", tt.name, pfx) + } + } + } + + // Ensure the original table isn't modified + for pfx, wantVal := range tt.prepare { + val, ok := tbl.Get(pfx) + if !ok { + t.Errorf("[%s] original table: key %v should be present", tt.name, pfx) + } + + if val != wantVal { + t.Errorf("[%s] original table: val %v is not as expected %v", tt.name, val, wantVal) + } + } + } +} + +func TestTableModifyCompare__TABLE_TYPE(t *testing.T) { + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[int]) + tbl := new(_TABLE_TYPE[int]) + + // Update as insert + for i, pfx := range pfxs { + gold.Insert(pfx, i) + tbl.Modify(pfx, func(int, bool) (int, bool) { return i, false }) + } + + gold.Sort() + tblFlat := tbl.flatSorted() + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[int]); isLite { + if !slices.Equal(gold.AllSorted(), tblFlat.AllSorted()) { + t.Fatal("expected Equal") + } + } else { + if !slices.Equal(*gold, tblFlat) { + t.Fatal("expected Equal") + } + } + + cb1 := func(val int, _ bool) int { return val + 1 } + cb2 := func(val int, _ bool) (int, bool) { return val + 1, false } + + // Update as update + for _, pfx := range pfxs[:len(pfxs)/2] { + gold.Update(pfx, cb1) + tbl.Modify(pfx, cb2) + } + + gold.Sort() + tblFlat = tbl.flatSorted() + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[int]); isLite { + if !slices.Equal(gold.AllSorted(), tblFlat.AllSorted()) { + t.Fatal("expected Equal") + } + } else { + if !slices.Equal(*gold, tblFlat) { + t.Fatal("expected Equal") + } + } +} + +func TestTableModifyPersistCompare__TABLE_TYPE(t *testing.T) { + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + mut := new(_TABLE_TYPE[int]) + imu := new(_TABLE_TYPE[int]) + + // Update as insert + for i, pfx := range pfxs { + mut.Modify(pfx, func(int, bool) (int, bool) { return i, false }) + imu = imu.ModifyPersist(pfx, func(int, bool) (int, bool) { return i, false }) + } + + if !mut.Equal(imu) { + t.Fatal("expected Equal") + } + + cb := func(val int, _ bool) (int, bool) { return val + 1, false } + + // Update as update + for _, pfx := range pfxs[:len(pfxs)/2] { + mut.Modify(pfx, cb) + imu = imu.ModifyPersist(pfx, cb) + } + + if !mut.Equal(imu) { + t.Fatal("expected Equal") + } +} + +func TestTableModifyShuffled__TABLE_TYPE(t *testing.T) { + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + + var ( + numPrefixes = n // prefixes to insert (test deletes 50% of them) + numPerFamily = numPrefixes / 2 + deleteCut = numPerFamily / 2 + ) + + for range 10 { + all4 := random.RealWorldPrefixes4(prng, numPerFamily) + all6 := random.RealWorldPrefixes6(prng, numPerFamily) + + // pfxs toDelete should be non-overlapping sets + pfxs := slices.Concat(all4, all6) + toDelete := slices.Concat(all4[deleteCut:], all6[deleteCut:]) + + tbl1 := new(_TABLE_TYPE[string]) + + // insert + for _, pfx := range pfxs { + tbl1.Insert(pfx, pfx.String()) + } + + // this callback deletes unconditionally + cb := func(string, bool) (string, bool) { return "", true } + + // delete + for _, pfx := range toDelete { + tbl1.Modify(pfx, cb) + } + + pfxs2 := slices.Clone(pfxs) + toDelete2 := slices.Clone(toDelete) + prng.Shuffle(len(toDelete2), func(i, j int) { toDelete2[i], toDelete2[j] = toDelete2[j], toDelete2[i] }) + + tbl2 := new(_TABLE_TYPE[string]) + + // insert + for _, pfx := range pfxs2 { + tbl2.Insert(pfx, pfx.String()) + } + + // delete + for _, pfx := range toDelete2 { + tbl2.Modify(pfx, cb) + } + + if !tbl1.Equal(tbl2) { + t.Fatal("expected equal") + } + } +} + +func TestTableModifyPersistShuffled__TABLE_TYPE(t *testing.T) { + t.Parallel() + + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + + var ( + numPrefixes = n // prefixes to insert (test deletes 50% of them) + numPerFamily = numPrefixes / 2 + deleteCut = numPerFamily / 2 + ) + + for range 10 { + all4 := random.RealWorldPrefixes4(prng, numPerFamily) + all6 := random.RealWorldPrefixes6(prng, numPerFamily) + + // pfxs toDelete should be non-overlapping sets + pfxs := slices.Concat(all4, all6) + toDelete := slices.Concat(all4[deleteCut:], all6[deleteCut:]) + + tbl1 := new(_TABLE_TYPE[string]) + + // insert + for _, pfx := range pfxs { + tbl1.Insert(pfx, pfx.String()) + } + + // this callback deletes unconditionally + cb := func(string, bool) (string, bool) { return "", true } + + // delete + for _, pfx := range toDelete { + tbl1 = tbl1.ModifyPersist(pfx, cb) + } + + pfxs2 := slices.Clone(pfxs) + toDelete2 := slices.Clone(toDelete) + prng.Shuffle(len(toDelete2), func(i, j int) { toDelete2[i], toDelete2[j] = toDelete2[j], toDelete2[i] }) + + tbl2 := new(_TABLE_TYPE[string]) + + // insert + for _, pfx := range pfxs2 { + tbl2.Insert(pfx, pfx.String()) + } + + // delete + for _, pfx := range toDelete2 { + tbl2 = tbl2.ModifyPersist(pfx, cb) + } + + if !tbl1.Equal(tbl2) { + t.Fatal("expected equal") + } + } +} + +// TestUnionMemoryAliasing tests that the Union method does not alias memory +// between the two tables. +func TestTableUnionMemoryAliasing__TABLE_TYPE(t *testing.T) { + t.Parallel() + + newTable := func(pfx ...string) *_TABLE_TYPE[any] { + tbl := new(_TABLE_TYPE[any]) + for _, s := range pfx { + tbl.Insert(mpp(s), nil) + } + return tbl + } + + // First create two tables with disjoint prefixes. + stable := newTable("0.0.0.0/24") + temp := newTable("100.69.1.0/24") + + // Verify that the tables are disjoint. + if stable.Overlaps(temp) { + t.Error("stable should not overlap temp") + } + + // Now union them. + temp.Union(stable) + + // Add a new prefix to temp. + temp.Insert(mpp("0.0.1.0/24"), struct{}{}) + + // Ensure that stable is unchanged. + _, ok := stable.Lookup(mpa("0.0.1.1")) + if ok { + t.Error("stable should not contain 0.0.1.1") + } + if stable.OverlapsPrefix(mpp("0.0.1.1/32")) { + t.Error("stable should not overlap 0.0.1.1/32") + } +} + +// TestUnionPersistMemoryAliasing tests that the Union method does not alias memory +// between the tables. +func TestTableUnionPersistMemoryAliasing__TABLE_TYPE(t *testing.T) { + t.Parallel() + + newTable := func(pfx ...string) *_TABLE_TYPE[any] { + tbl := new(_TABLE_TYPE[any]) + for _, s := range pfx { + tbl.Insert(mpp(s), nil) + } + return tbl + } + // First create two tables with disjoint prefixes. + a := newTable("100.69.1.0/24") + b := newTable("0.0.0.0/24") + + // Verify that the tables are disjoint. + if a.Overlaps(b) { + t.Error("this should not overlap other") + } + + // Now union them with copy-on-write. + pTbl := a.UnionPersist(b) + + // Add a new prefix to new union + pTbl.Insert(mpp("0.0.1.0/24"), struct{}{}) + + // Ensure that a is unchanged. + _, ok := a.Lookup(mpa("0.0.1.1")) + if ok { + t.Error("a should not contain 0.0.1.1") + } + if a.OverlapsPrefix(mpp("0.0.1.1/32")) { + t.Error("a should not overlap 0.0.1.1/32") + } +} + +func TestTableUnionCompare__TABLE_TYPE(t *testing.T) { + t.Parallel() + + n := workLoadN() + prng := rand.New(rand.NewPCG(42, 42)) + + for range 3 { + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[string]) + tbl := new(_TABLE_TYPE[string]) + + for _, pfx := range pfxs { + gold.Insert(pfx, pfx.String()) + tbl.Insert(pfx, pfx.String()) + } + + pfxs2 := random.RealWorldPrefixes(prng, n) + + gold2 := new(golden.Table[string]) + tbl2 := new(_TABLE_TYPE[string]) + + for _, pfx := range pfxs2 { + gold2.Insert(pfx, pfx.String()) + tbl2.Insert(pfx, pfx.String()) + } + + gold.Union(gold2) + tbl.Union(tbl2) + + // dump as slow table for comparison + tblFlat := tbl.flatSorted() + + // sort for comparison + gold.Sort() + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[string]); isLite { + if !slices.Equal(gold.AllSorted(), tblFlat.AllSorted()) { + t.Fatal("expected Equal") + } + } else { + if !slices.Equal(*gold, tblFlat) { + t.Fatal("expected Equal") + } + } + } +} + +func TestTableUnionPersistCompare__TABLE_TYPE(t *testing.T) { + t.Parallel() + prng := rand.New(rand.NewPCG(42, 42)) + + n := workLoadN() + + for range 3 { + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[int]) + tbl := new(_TABLE_TYPE[int]) + + for i, pfx := range pfxs { + gold.Insert(pfx, i) + tbl.Insert(pfx, i) + } + + pfxs2 := random.RealWorldPrefixes(prng, n) + + gold2 := new(golden.Table[int]) + tbl2 := new(_TABLE_TYPE[int]) + + for i, pfx := range pfxs2 { + gold2.Insert(pfx, i) + tbl2.Insert(pfx, i) + } + + gold.Union(gold2) + tblP := tbl.UnionPersist(tbl2) + + // dump as slow table for comparison + flatP := tblP.flatSorted() + + // sort for comparison + gold.Sort() + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[int]); isLite { + if !slices.Equal(gold.AllSorted(), flatP.AllSorted()) { + t.Fatal("expected Equal") + } + } else { + if !slices.Equal(*gold, flatP) { + t.Fatal("expected Equal") + } + } + } +} + +func TestTableClone__TABLE_TYPE(t *testing.T) { + t.Parallel() + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + tbl := new(_TABLE_TYPE[int]) + for i, pfx := range pfxs { + tbl.Insert(pfx, i) + } + clone := tbl.Clone() + + if !tbl.Equal(clone) { + t.Fatal("expected equal") + } +} + +func TestTableCloneShallow__TABLE_TYPE(t *testing.T) { + t.Parallel() + + tbl := new(_TABLE_TYPE[*int]) + + if _, isLite := any(tbl).(*liteTable[*int]); isLite { + t.Skip("liteNode has no real payload") + } + + clone := tbl.Clone() + if tbl.dumpString() != clone.dumpString() { + t.Errorf("empty Clone: got:\n%swant:\n%s", clone.dumpString(), tbl.dumpString()) + } + + val := 1 + pfx := mpp("10.0.0.1/32") + tbl.Insert(pfx, &val) + + clone = tbl.Clone() + want, _ := tbl.Get(pfx) + got, _ := clone.Get(pfx) + + if *got != *want || got != want { + t.Errorf("shallow copy, values and pointers must be equal:\nvalues(%d, %d)\n(ptr(%v, %v)", *got, *want, got, want) + } + + // update value, shallow copy of values, clone must be equal + val = 2 + want, _ = tbl.Get(pfx) + got, _ = clone.Get(pfx) + + if *got != *want { + t.Errorf("memory aliasing after shallow copy, values must be equal:\nvalues(%d, %d)", *got, *want) + } +} + +func TestTableCloneDeep__TABLE_TYPE(t *testing.T) { + t.Parallel() + + tbl := new(_TABLE_TYPE[*MyInt]) + + if _, isLite := any(tbl).(*liteTable[*MyInt]); isLite { + t.Skip("liteNode has no real payload") + } + + clone := tbl.Clone() + if tbl.dumpString() != clone.dumpString() { + t.Errorf("empty Clone: got:\n%swant:\n%s", clone.dumpString(), tbl.dumpString()) + } + + val := MyInt(1) + pfx := mpp("10.0.0.1/32") + tbl.Insert(pfx, &val) + + clone = tbl.Clone() + want, _ := tbl.Get(pfx) + got, _ := clone.Get(pfx) + + if *got != *want || got == want { + t.Errorf("value with Cloner interface, pointers must be different:\nvalues(%d, %d)\n(ptr(%v, %v)", *got, *want, got, want) + } + + // update value, deep copy of values, cloned value must now be different + val = 2 + want, _ = tbl.Get(pfx) + got, _ = clone.Get(pfx) + + if *got == *want { + t.Errorf("memory aliasing after deep copy, values must be different:\nvalues(%d, %d)", *got, *want) + } +} + +func TestTableUnionShallow__TABLE_TYPE(t *testing.T) { + t.Parallel() + + tbl1 := new(_TABLE_TYPE[*int]) + tbl2 := new(_TABLE_TYPE[*int]) + + if _, isLite := any(tbl1).(*liteTable[*int]); isLite { + t.Skip("liteNode has no real payload") + } + + val := 1 + pfx := mpp("10.0.0.1/32") + tbl2.Insert(pfx, &val) + + tbl1.Union(tbl2) + got, _ := tbl1.Get(pfx) + want, _ := tbl2.Get(pfx) + + if *got != *want || got != want { + t.Errorf("shallow copy, values and pointers must be equal:\nvalues(%d, %d)\n(ptr(%v, %v)", *got, *want, got, want) + } + + // update value, shallow copy of values, union must be equal + val = 2 + got, _ = tbl1.Get(pfx) + want, _ = tbl2.Get(pfx) + + if *got != *want { + t.Errorf("memory aliasing after shallow copy, values must be equal:\nvalues(%d, %d)", *got, *want) + } +} + +func TestTableUnionDeep__TABLE_TYPE(t *testing.T) { + t.Parallel() + + tbl1 := new(_TABLE_TYPE[*MyInt]) + tbl2 := new(_TABLE_TYPE[*MyInt]) + + if _, isLite := any(tbl1).(*liteTable[*MyInt]); isLite { + t.Skip("liteNode has no real payload") + } + + val := MyInt(1) + pfx := mpp("10.0.0.1/32") + tbl2.Insert(pfx, &val) + + tbl1.Union(tbl2) + got, _ := tbl1.Get(pfx) + want, _ := tbl2.Get(pfx) + + if *got != *want || got == want { + t.Errorf("value with Cloner interface, pointers must be different:\nvalues(%d, %d)\n(ptr(%v, %v)", *got, *want, got, want) + } + + // update value, shallow copy of values, union must be equal + val = 2 + got, _ = tbl1.Get(pfx) + want, _ = tbl2.Get(pfx) + + if *got == *want { + t.Errorf("memory aliasing after deep copy, values must be different:\nvalues(%d, %d)", *got, *want) + } +} + +// test some edge cases +func TestTableOverlapsPrefixEdgeCases__TABLE_TYPE(t *testing.T) { + t.Parallel() + + type probe struct { + pfx netip.Prefix + want bool + } + + type probes []probe + type pfxs []netip.Prefix + + type test struct { + name string + insert pfxs + probes probes + } + + tests := []test{ + { + name: "empty table", + insert: nil, + probes: probes{{mpp("0.0.0.0/0"), false}, {mpp("::/0"), false}}, + }, + { + name: "default route I", + insert: pfxs{mpp("10.0.0.0/9"), mpp("2001:db8::/32")}, + probes: probes{{mpp("0.0.0.0/0"), true}, {mpp("::/0"), true}}, + }, + { + name: "default route II", + insert: pfxs{mpp("0.0.0.0/0"), mpp("::/0")}, + probes: probes{{mpp("10.0.0.0/9"), true}, {mpp("2001:db8::/32"), true}}, + }, + { + name: "single IP I", + insert: pfxs{mpp("10.0.0.0/7"), mpp("2001::/16")}, + probes: probes{{mpp("10.1.2.3/32"), true}, {mpp("2001:db8:affe::cafe/128"), true}}, + }, + { + name: "single IP II", + insert: pfxs{mpp("10.1.2.3/32"), mpp("2001:db8:affe::cafe/128")}, + probes: probes{{mpp("10.0.0.0/7"), true}, {mpp("2001::/16"), true}}, + }, + { + name: "same IP", + insert: pfxs{mpp("10.1.2.3/32"), mpp("2001:db8:affe::cafe/128")}, + probes: probes{{mpp("10.1.2.3/32"), true}, {mpp("2001:db8:affe::cafe/128"), true}}, + }, + } + + for _, tt := range tests { + tbl := new(_TABLE_TYPE[int]) + for _, pfx := range tt.insert { + tbl.Insert(pfx, 0) + } + + for _, probe := range tt.probes { + got := tbl.OverlapsPrefix(probe.pfx) + if got != probe.want { + t.Errorf("[%s] OverlapsPrefix(%v) = %v, want %v", tt.name, probe.pfx, got, probe.want) + } + } + } +} + +func TestTableSize__TABLE_TYPE(t *testing.T) { + t.Parallel() + + n := workLoadN() + prng := rand.New(rand.NewPCG(42, 42)) + + tbl := new(_TABLE_TYPE[any]) + if tbl.Size() != 0 { + t.Errorf("empty Table: want: 0, got: %d", tbl.Size()) + } + + if tbl.Size4() != 0 { + t.Errorf("empty Table: want: 0, got: %d", tbl.Size4()) + } + + if tbl.Size6() != 0 { + t.Errorf("empty Table: want: 0, got: %d", tbl.Size6()) + } + + pfxs1 := random.RealWorldPrefixes(prng, n) + pfxs2 := random.RealWorldPrefixes(prng, n) + + for _, pfx := range pfxs1 { + tbl.Insert(pfx, nil) + } + + for _, pfx := range pfxs2 { + tbl.Modify(pfx, func(any, bool) (any, bool) { return nil, false }) + } + + pfxs1 = append(pfxs1, pfxs2...) + + for _, pfx := range pfxs1[:n] { + tbl.Modify(pfx, func(any, bool) (any, bool) { return nil, false }) + } + + for _, pfx := range random.RealWorldPrefixes(prng, n) { + tbl.Delete(pfx) + } + + var allCount4 int + var allCount6 int + + for range tbl.AllSorted4() { + allCount4++ + } + + for range tbl.AllSorted6() { + allCount6++ + } + + if allCount4 != tbl.Size4() { + t.Errorf("Size4: want: %d, got: %d", allCount4, tbl.Size4()) + } + + if allCount6 != tbl.Size6() { + t.Errorf("Size6: want: %d, got: %d", allCount6, tbl.Size6()) + } +} + +// TestAll tests All with random samples +func TestTableAll__TABLE_TYPE(t *testing.T) { + t.Parallel() + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + pfxs := random.RealWorldPrefixes(prng, n) + + tbl := new(_TABLE_TYPE[string]) + + // Insert all prefixes with their values + for _, pfx := range pfxs { + tbl.Insert(pfx, pfx.String()) + } + + // Collect all prefixes from All + gotPrefixes := make([]netip.Prefix, 0, n) + gotValues := make([]string, 0, n) + + for pfx, val := range tbl.All() { + gotPrefixes = append(gotPrefixes, pfx) + gotValues = append(gotValues, val) + } + + // Collect all prefixes from All4 and All6 + got4Prefixes := make([]netip.Prefix, 0, n) + got4Values := make([]string, 0, n) + + for pfx, val := range tbl.All4() { + got4Prefixes = append(got4Prefixes, pfx) + got4Values = append(got4Values, val) + } + + got6Prefixes := make([]netip.Prefix, 0, n) + got6Values := make([]string, 0, n) + for pfx, val := range tbl.All6() { + got6Prefixes = append(got6Prefixes, pfx) + got6Values = append(got6Values, val) + } + + // Verify we got exactly the same number of prefixes + if len(gotPrefixes) != len(pfxs) { + t.Fatalf("Expected %d prefixes, got %d", len(pfxs), len(gotPrefixes)) + } + + if len(got4Prefixes)+len(got6Prefixes) != len(pfxs) { + t.Fatalf("Expected %d prefixes, got %d", len(pfxs), len(got4Prefixes)+len(got6Prefixes)) + } + + if !slices.Equal(slices.Concat(got4Prefixes, got6Prefixes), gotPrefixes) { + t.Fatal("Prefixes: All4 + All6 != All") + } + if !slices.Equal(slices.Concat(got4Values, got6Values), gotValues) { + t.Fatal("Values: All4 + All6 != All") + } + + // Verify we can find each original prefix in the results + // Create a map for O(1) lookup verification + resultMap := make(map[netip.Prefix]string, n) + for i, pfx := range gotPrefixes { + resultMap[pfx] = gotValues[i] + } + + for _, pfx := range pfxs { + val, found := resultMap[pfx] + if !found { + t.Fatalf("Original prefix %v not found in All results", pfx) + } + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[string]); !isLite { + if val != pfx.String() { + t.Fatalf("Original prefix %v has wrong value: expected %s, got %s", + pfx, pfx.String(), val) + } + } + } + + // Verify no duplicates in results + seen := make(map[netip.Prefix]bool, n) + for _, pfx := range gotPrefixes { + if seen[pfx] { + t.Fatalf("Duplicate prefix %v found in All results", pfx) + } + seen[pfx] = true + } +} + +func TestTableAllSorted__TABLE_TYPE(t *testing.T) { + t.Parallel() + + // Test cases with known CIDR sort order + testCases := []struct { + name string + prefixes []string + expected []string // Expected order after sorting + }{ + { + name: "Mixed IPv4 addresses and prefix lengths", + prefixes: []string{ + "10.0.0.0/16", + "10.0.0.0/8", + "192.168.1.0/24", + "10.0.0.0/24", + "172.16.0.0/12", + }, + expected: []string{ + "10.0.0.0/8", // Same address, shorter prefix first + "10.0.0.0/16", // Same address, longer prefix + "10.0.0.0/24", // Same address, longest prefix + "172.16.0.0/12", // Next address + "192.168.1.0/24", // Highest address + }, + }, + { + name: "Mixed IPv6 addresses and prefix lengths", + prefixes: []string{ + "2001:db8::/32", + "2001:db8::/64", + "2000::/16", + "2001:db8:1::/48", + }, + expected: []string{ + "2000::/16", // Lowest address + "2001:db8::/32", // Same address, shorter prefix first + "2001:db8::/64", // Same address, longer prefix + "2001:db8:1::/48", // Higher address + }, + }, + { + name: "Mixed IPv4 and IPv6", + prefixes: []string{ + "192.168.1.0/24", + "2001:db8::/32", + "10.0.0.0/8", + "::1/128", + }, + expected: []string{ + "10.0.0.0/8", // IPv4 addresses come first (lower in comparison) + "192.168.1.0/24", // Next IPv4 address + "::1/128", // IPv6 addresses after IPv4 + "2001:db8::/32", // Higher IPv6 address + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + tbl := new(_TABLE_TYPE[int]) + + // Insert prefixes with index as value + for i, prefixStr := range tc.prefixes { + pfx := netip.MustParsePrefix(prefixStr) + tbl.Insert(pfx, i) + } + + // Collect sorted results + var actualOrder []string + for pfx := range tbl.AllSorted() { + actualOrder = append(actualOrder, pfx.String()) + } + + // Verify the order matches expected + if len(actualOrder) != len(tc.expected) { + t.Fatalf("%s: Expected %d results, got %d", tc.name, len(tc.expected), len(actualOrder)) + } + + // Collect sorted 4 results + var actual4Order []string + for pfx := range tbl.AllSorted4() { + actual4Order = append(actual4Order, pfx.String()) + } + + // Collect sorted 6 results + var actual6Order []string + for pfx := range tbl.AllSorted6() { + actual6Order = append(actual6Order, pfx.String()) + } + + if !slices.Equal(slices.Concat(actual4Order, actual6Order), actualOrder) { + t.Fatalf("%s: Prefixes: AllSorted4 + AllSorted6 != AllSorted", tc.name) + } + + for i, expected := range tc.expected { + if actualOrder[i] != expected { + t.Errorf("%s:At position %d: expected %s, got %s", tc.name, i, expected, actualOrder[i]) + t.Errorf("%s:Full expected order: %v", tc.name, tc.expected) + t.Errorf("%s:Full actual order: %v", tc.name, actualOrder) + break + } + } + }) + } +} + +func TestTableSubnets__TABLE_TYPE(t *testing.T) { + t.Parallel() + + var zeroPfx netip.Prefix + + t.Run("empty table", func(t *testing.T) { + t.Parallel() + tbl := new(_TABLE_TYPE[string]) + pfx := mpp("::1/128") + + for range tbl.Subnets(pfx) { + t.Errorf("empty table, must not range over") + } + }) + + t.Run("invalid prefix", func(t *testing.T) { + tbl := new(_TABLE_TYPE[string]) + pfx := mpp("::1/128") + val := "foo" + tbl.Insert(pfx, val) + for range tbl.Subnets(zeroPfx) { + t.Errorf("invalid prefix, must not range over") + } + }) + + t.Run("identity", func(t *testing.T) { + tbl := new(_TABLE_TYPE[string]) + pfx := mpp("::1/128") + val := "foo" + tbl.Insert(pfx, val) + + for p, v := range tbl.Subnets(pfx) { + if p != pfx { + t.Errorf("Subnet(%v), got: %v, want: %v", pfx, p, pfx) + } + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[string]); !isLite { + if v != val { + t.Errorf("Subnet(%v), got: %v, want: %v", pfx, v, val) + } + } + } + }) + + t.Run("default gateway", func(t *testing.T) { + n := workLoadN() + prng := rand.New(rand.NewPCG(42, 42)) + + want4 := n - n/2 + want6 := n + n/2 + + tbl := new(_TABLE_TYPE[int]) + for i, pfx := range random.RealWorldPrefixes4(prng, want4) { + tbl.Insert(pfx, i) + } + for i, pfx := range random.RealWorldPrefixes6(prng, want6) { + tbl.Insert(pfx, i) + } + + // default gateway v4 covers all v4 prefixes in table + dg4 := mpp("0.0.0.0/0") + got4 := 0 + for range tbl.Subnets(dg4) { + got4++ + } + + // default gateway v6 covers all v6 prefixes in table + dg6 := mpp("::/0") + got6 := 0 + for range tbl.Subnets(dg6) { + got6++ + } + + if got4 != want4 { + t.Errorf("Subnets v4, want: %d, got: %d", want4, got4) + } + if got6 != want6 { + t.Errorf("Subnets v6, want: %d, got: %d", want6, got6) + } + }) +} + +func TestTableSubnetsCompare__TABLE_TYPE(t *testing.T) { + t.Parallel() + n := workLoadN() + prng := rand.New(rand.NewPCG(42, 42)) + + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[int]) + tbl := new(_TABLE_TYPE[int]) + + for i, pfx := range pfxs { + gold.Insert(pfx, i) + tbl.Insert(pfx, i) + } + + for _, pfx := range random.RealWorldPrefixes(prng, n) { + t.Run("subtest", func(t *testing.T) { + t.Parallel() + + gotGold := gold.Subnets(pfx) + gotTbl := []netip.Prefix{} + for pfx := range tbl.Subnets(pfx) { + gotTbl = append(gotTbl, pfx) + } + if !slices.Equal(gotGold, gotTbl) { + t.Fatalf("Subnets(%q) = %v, want %v", pfx, gotTbl, gotGold) + } + }) + } +} + +func TestTableSupernetsEdgeCase__TABLE_TYPE(t *testing.T) { + t.Parallel() + + var zeroPfx netip.Prefix + + t.Run("empty table", func(t *testing.T) { + t.Parallel() + tbl := new(_TABLE_TYPE[any]) + pfx := mpp("::1/128") + + tbl.Supernets(pfx)(func(_ netip.Prefix, _ any) bool { + t.Errorf("empty table, must not range over") + return false + }) + }) + + t.Run("invalid prefix", func(t *testing.T) { + tbl := new(_TABLE_TYPE[any]) + pfx := mpp("::1/128") + val := "foo" + tbl.Insert(pfx, val) + + tbl.Supernets(zeroPfx)(func(_ netip.Prefix, _ any) bool { + t.Errorf("invalid prefix, must not range over") + return false + }) + }) + + t.Run("identity", func(t *testing.T) { + tbl := new(_TABLE_TYPE[string]) + pfx := mpp("::1/128") + val := "foo" + tbl.Insert(pfx, val) + + for p, v := range tbl.Supernets(pfx) { + if p != pfx { + t.Errorf("Supernets(%v), got: %v, want: %v", pfx, p, pfx) + } + + // Skip value comparison for liteTable (no real payload) + if _, isLite := any(tbl).(*liteTable[string]); !isLite { + if v != val { + t.Errorf("Supernets(%v), got: %v, want: %v", pfx, v, val) + } + } + } + }) +} + +func TestTableSupernetsCompare__TABLE_TYPE(t *testing.T) { + t.Parallel() + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + + pfxs := random.RealWorldPrefixes(prng, n) + + gold := new(golden.Table[int]) + tbl := new(_TABLE_TYPE[int]) + + for i, pfx := range pfxs { + gold.Insert(pfx, i) + tbl.Insert(pfx, i) + } + + for _, pfx := range random.RealWorldPrefixes(prng, n) { + t.Run("subtest", func(t *testing.T) { + t.Parallel() + gotGold := gold.Supernets(pfx) + gotTbl := []netip.Prefix{} + + for p := range tbl.Supernets(pfx) { + gotTbl = append(gotTbl, p) + } + + if !slices.Equal(gotGold, gotTbl) { + t.Fatalf("Supernets(%q) = %v, want %v", pfx, gotTbl, gotGold) + } + }) + } +} + +func TestTableMarshalText__TABLE_TYPE(t *testing.T) { + tests := []struct { + name string + expectedData map[netip.Prefix]string + }{ + { + name: "empty", + expectedData: map[netip.Prefix]string{}, + }, + { + name: "with_data", + expectedData: map[netip.Prefix]string{ + mpp("192.168.1.0/24"): "test1", + mpp("10.0.0.0/8"): "test2", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tbl := new(_TABLE_TYPE[string]) + + // Insert test data + for prefix, value := range tt.expectedData { + tbl.Insert(prefix, value) + } + + data, err := tbl.MarshalText() + if err != nil { + t.Errorf("MarshalText failed: %v", err) + } + + if len(tt.expectedData) > 0 && len(data) == 0 { + t.Error("Expected non-empty marshaled text") + } + + // Check that all expected values appear in marshaled text + text := string(data) + for _, value := range tt.expectedData { + if !strings.Contains(text, value) { + t.Errorf("Marshaled text doesn't contain expected value: %s", value) + } + } + }) + } +} + +func TestTableMarshalJSON__TABLE_TYPE(t *testing.T) { + tests := []struct { + name string + expectedData map[netip.Prefix]any + }{ + { + name: "empty", + expectedData: map[netip.Prefix]any{}, + }, + { + name: "string_values", + expectedData: map[netip.Prefix]any{ + mpp("192.168.1.0/24"): "net1", + mpp("10.0.0.0/8"): "net2", + }, + }, + { + name: "mixed_values", + expectedData: map[netip.Prefix]any{ + mpp("192.168.1.0/24"): "string", + mpp("10.0.0.0/8"): 42, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tbl := new(_TABLE_TYPE[any]) + + // Insert test data + for prefix, value := range tt.expectedData { + tbl.Insert(prefix, value) + } + + jsonData, err := tbl.MarshalJSON() + if err != nil { + t.Errorf("JSON marshaling failed: %v", err) + } + + if len(jsonData) == 0 { + t.Error("Expected valid JSON") + } + + // Should be valid JSON + var result interface{} + if err := json.Unmarshal(jsonData, &result); err != nil { + t.Errorf("Invalid JSON produced: %v", err) + } + }) + } +} + +func TestTableDumpList4__TABLE_TYPE(t *testing.T) { + tests := []struct { + name string + expectedData map[netip.Prefix]string + expectItems int + }{ + { + name: "empty", + expectedData: map[netip.Prefix]string{}, + expectItems: 0, + }, + { + name: "single_ipv4", + expectedData: map[netip.Prefix]string{ + mpp("192.168.1.0/24"): "lan", + }, + expectItems: 1, + }, + { + name: "multiple_ipv4", + expectedData: map[netip.Prefix]string{ + mpp("192.168.1.0/24"): "lan", + mpp("10.0.0.0/8"): "private", + }, + expectItems: 2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tbl := new(_TABLE_TYPE[string]) + + // Insert test data + for prefix, value := range tt.expectedData { + tbl.Insert(prefix, value) + } + + dumpList := tbl.DumpList4() + + // Count total nodes in the tree (including nested) + totalNodes := countDumpListNodes(dumpList) + if totalNodes != tt.expectItems { + t.Errorf("DumpList4() total nodes (%d) does not match expected (%d)", totalNodes, tt.expectItems) + } + + // Verify all nodes are IPv4 + verifyAllIPv4Nodes(t, dumpList) + }) + } +} + +func TestTableDumpList6__TABLE_TYPE(t *testing.T) { + tests := []struct { + name string + expectedData map[netip.Prefix]string + expectItems int + }{ + { + name: "empty", + expectedData: map[netip.Prefix]string{}, + expectItems: 0, + }, + { + name: "single_ipv6", + expectedData: map[netip.Prefix]string{ + mpp("2001:db8::/32"): "doc", + }, + expectItems: 1, + }, + { + name: "multiple_ipv6", + expectedData: map[netip.Prefix]string{ + mpp("2001:db8::/32"): "doc", + mpp("fe80::/10"): "link-local", + }, + expectItems: 2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tbl := new(_TABLE_TYPE[string]) + + // Insert test data + for prefix, value := range tt.expectedData { + tbl.Insert(prefix, value) + } + + dumpList := tbl.DumpList6() + + // Count total nodes in the tree (including nested) + totalNodes := countDumpListNodes(dumpList) + if totalNodes != tt.expectItems { + t.Errorf("DumpList6() total nodes (%d) does not match expected (%d)", totalNodes, tt.expectItems) + } + + // Verify all nodes are IPv6 + verifyAllIPv6Nodes(t, dumpList) + }) + } +} + +func TestTableEqual__TABLE_TYPE(t *testing.T) { + t.Parallel() + + n := workLoadN() + prng := rand.New(rand.NewPCG(42, 42)) + + at := new(_TABLE_TYPE[int]) + for i, pfx := range random.RealWorldPrefixes(prng, n) { + at.Insert(pfx, i) + } + + t.Run("clone", func(t *testing.T) { + t.Parallel() + bt := at.Clone() + if !at.Equal(bt) { + t.Error("expected true, got false") + } + }) +} + +func TestTableExtra__TABLE_TYPE(t *testing.T) { + t.Parallel() + + // 1. Equal: checking self equality + t1 := new(_TABLE_TYPE[int]) + t1.Insert(mpp("10.0.0.0/8"), 42) + t1.Insert(mpp("2001:db8::/32"), 42) + + if !t1.Equal(t1) { + t.Error("expected table to be equal to itself") + } + + // 2. Equal: checking different size4 / size6 + t2 := new(_TABLE_TYPE[int]) + t2.Insert(mpp("10.0.0.0/8"), 42) + if t1.Equal(t2) { + t.Error("expected false for different size6") + } + + t3 := new(_TABLE_TYPE[int]) + t3.Insert(mpp("2001:db8::/32"), 42) + if t1.Equal(t3) { + t.Error("expected false for different size4") + } + + // 3. Overlaps6: checking when size6 is 0 + emptyT := new(_TABLE_TYPE[int]) + if t1.Overlaps6(emptyT) { + t.Error("expected false when other table has no IPv6 prefixes") + } + if emptyT.Overlaps6(t1) { + t.Error("expected false when this table has no IPv6 prefixes") + } + + // 4. Fprint: nil writer check + var nilWriter io.Writer = nil + if err := t1.Fprint(nilWriter); err == nil { + t.Error("expected error when writing to nil writer") + } + + // 5. ModifyPersist: no-op deletion of non-existing key + t4 := new(_TABLE_TYPE[int]) + t5 := t4.ModifyPersist(mpp("10.0.0.0/8"), func(val int, ok bool) (int, bool) { + return 0, true + }) + if t5 != t4 { + t.Error("expected same table pointer for no-op ModifyPersist") + } +} diff --git a/vendor/github.com/gaissmai/bart/dumper.go b/vendor/github.com/gaissmai/bart/dumper.go deleted file mode 100644 index 97e15b7..0000000 --- a/vendor/github.com/gaissmai/bart/dumper.go +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright (c) 2024 Karl Gaissmaier -// SPDX-License-Identifier: MIT - -package bart - -import ( - "fmt" - "io" - "strconv" - "strings" -) - -type nodeType byte - -const ( - nullNode nodeType = iota // empty node - fullNode // prefixes and children or path-compressed prefixes - leafNode // no children, only prefixes or path-compressed prefixes - intermediateNode // only children, no prefix nor path-compressed prefixes -) - -// ################################################## -// useful during development, debugging and testing -// ################################################## - -// dumpString is just a wrapper for dump. -func (t *Table[V]) dumpString() string { - w := new(strings.Builder) - t.dump(w) - - return w.String() -} - -// dump the table structure and all the nodes to w. -func (t *Table[V]) dump(w io.Writer) { - if t == nil { - return - } - - if t.size4 > 0 { - fmt.Fprintln(w) - fmt.Fprintf(w, "### IPv4: size(%d), nodes(%d)", t.size4, t.root4.nodeStatsRec().nodes) - t.root4.dumpRec(w, stridePath{}, 0, true) - } - - if t.size6 > 0 { - fmt.Fprintln(w) - fmt.Fprintf(w, "### IPv6: size(%d), nodes(%d)", t.size6, t.root6.nodeStatsRec().nodes) - t.root6.dumpRec(w, stridePath{}, 0, false) - } -} - -// dumpRec, rec-descent the trie. -func (n *node[V]) dumpRec(w io.Writer, path stridePath, depth int, is4 bool) { - // dump this node - n.dump(w, path, depth, is4) - - // the node may have childs, rec-descent down - for i, addr := range n.children.All() { - octet := byte(addr) - path[depth] = octet - - if child, ok := n.children.Items[i].(*node[V]); ok { - child.dumpRec(w, path, depth+1, is4) - } - } -} - -// dump the node to w. -func (n *node[V]) dump(w io.Writer, path stridePath, depth int, is4 bool) { - bits := depth * strideLen - indent := strings.Repeat(".", depth) - - // node type with depth and octet path and bits. - fmt.Fprintf(w, "\n%s[%s] depth: %d path: [%s] / %d\n", - indent, n.hasType(), depth, ipStridePath(path, depth, is4), bits) - - if nPfxCount := n.prefixes.Len(); nPfxCount != 0 { - // no heap allocs - allIndices := n.prefixes.All() - - // print the baseIndices for this node. - fmt.Fprintf(w, "%sindexs(#%d): %v\n", indent, nPfxCount, allIndices) - - // print the prefixes for this node - fmt.Fprintf(w, "%sprefxs(#%d):", indent, nPfxCount) - - for _, idx := range allIndices { - octet, pfxLen := idxToPfx(idx) - fmt.Fprintf(w, " %s/%d", octetFmt(octet, is4), pfxLen) - } - - fmt.Fprintln(w) - - // print the values for this node - fmt.Fprintf(w, "%svalues(#%d):", indent, nPfxCount) - - for _, val := range n.prefixes.Items { - fmt.Fprintf(w, " %v", val) - } - - fmt.Fprintln(w) - } - - if n.children.Len() != 0 { - - nodeAddrs := make([]uint, 0, maxNodeChildren) - leafAddrs := make([]uint, 0, maxNodeChildren) - - // the node has recursive child nodes or path-compressed leaves - for i, addr := range n.children.All() { - switch n.children.Items[i].(type) { - case *node[V]: - nodeAddrs = append(nodeAddrs, addr) - continue - - case *leaf[V]: - leafAddrs = append(leafAddrs, addr) - - default: - panic("logic error, wrong node type") - } - } - - if nodeCount := len(nodeAddrs); nodeCount > 0 { - // print the childs for this node - fmt.Fprintf(w, "%schilds(#%d):", indent, nodeCount) - - for _, addr := range nodeAddrs { - octet := byte(addr) - fmt.Fprintf(w, " %s", octetFmt(octet, is4)) - } - - fmt.Fprintln(w) - } - - if leafCount := len(leafAddrs); leafCount > 0 { - // print the pathcomp prefixes for this node - fmt.Fprintf(w, "%sleaves(#%d):", indent, leafCount) - - for _, addr := range leafAddrs { - octet := byte(addr) - k := n.children.MustGet(addr) - pc := k.(*leaf[V]) - - fmt.Fprintf(w, " %s:{%s, %v}", octetFmt(octet, is4), pc.prefix, pc.value) - } - fmt.Fprintln(w) - } - } -} - -// hasType returns the nodeType. -func (n *node[V]) hasType() nodeType { - s := n.nodeStats() - - switch { - case s.pfxs == 0 && s.childs == 0: - return nullNode - case s.nodes == 0: - return leafNode - case (s.pfxs > 0 || s.leaves > 0) && s.nodes > 0: - return fullNode - case (s.pfxs == 0 && s.leaves == 0) && s.nodes > 0: - return intermediateNode - default: - panic(fmt.Sprintf("UNREACHABLE: pfx: %d, chld: %d, node: %d, leaf: %d", - s.pfxs, s.childs, s.nodes, s.leaves)) - } -} - -// octetFmt, different format strings for IPv4 and IPv6, decimal versus hex. -func octetFmt(octet byte, is4 bool) string { - if is4 { - return fmt.Sprintf("%d", octet) - } - - return fmt.Sprintf("0x%02x", octet) -} - -// ip stride path, different formats for IPv4 and IPv6, dotted decimal or hex. -// -// 127.0.0 -// 2001:0d -func ipStridePath(path stridePath, depth int, is4 bool) string { - buf := new(strings.Builder) - - if is4 { - for i, b := range path[:depth] { - if i != 0 { - buf.WriteString(".") - } - - buf.WriteString(strconv.Itoa(int(b))) - } - - return buf.String() - } - - for i, b := range path[:depth] { - if i != 0 && i%2 == 0 { - buf.WriteString(":") - } - - buf.WriteString(fmt.Sprintf("%02x", b)) - } - - return buf.String() -} - -// String implements Stringer for nodeType. -func (nt nodeType) String() string { - switch nt { - case nullNode: - return "NULL" - case fullNode: - return "FULL" - case leafNode: - return "LEAF" - case intermediateNode: - return "IMED" - default: - return "unreachable" - } -} - -// stats, only used for dump, tests and benchmarks -type stats struct { - pfxs int - childs int - nodes int - leaves int -} - -// node statistics for this single node -func (n *node[V]) nodeStats() stats { - var s stats - - s.pfxs = n.prefixes.Len() - s.childs = n.children.Len() - - for i := range n.children.All() { - switch n.children.Items[i].(type) { - case *node[V]: - s.nodes++ - - case *leaf[V]: - s.leaves++ - - default: - panic("logic error, wrong node type") - } - } - - return s -} - -// nodeStatsRec, calculate the number of pfxs, nodes and leaves under n, rec-descent. -func (n *node[V]) nodeStatsRec() stats { - var s stats - if n == nil || n.isEmpty() { - return s - } - - s.pfxs = n.prefixes.Len() - s.childs = n.children.Len() - s.nodes = 1 // this node - s.leaves = 0 - - for _, kidAny := range n.children.Items { - switch kid := kidAny.(type) { - case *node[V]: - // rec-descent - rs := kid.nodeStatsRec() - - s.pfxs += rs.pfxs - s.childs += rs.childs - s.nodes += rs.nodes - s.leaves += rs.leaves - - case *leaf[V]: - s.leaves++ - - default: - panic("logic error, wrong node type") - } - } - - return s -} diff --git a/vendor/github.com/gaissmai/bart/fast.go b/vendor/github.com/gaissmai/bart/fast.go new file mode 100644 index 0000000..db1c710 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/fast.go @@ -0,0 +1,399 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package bart + +import ( + "net/netip" + "sync" + + "github.com/gaissmai/bart/internal/art" + "github.com/gaissmai/bart/internal/lpm" + "github.com/gaissmai/bart/internal/nodes" +) + +// Fast is similar to Table but uses additional 256 bytes in each node +// for faster level traversing in the multibit trie. +// +// As a result Fast sacrifices memory efficiency to achieve 25% better +// speed in lookup and contains. +// +// The zero value is ready to use. +// +// A Fast must not be copied by value; always pass by pointer. +// Nil pointers as receivers or arguments are forbidden and will panic. +// +// The Fast is safe for concurrent reads, but concurrent reads and writes +// must be externally synchronized. Mutation via Insert/Delete requires locks, +// or alternatively, use ...Persist methods which return a modified copy +// without altering the original table (copy-on-write). +// +// Performance note: Do not pass IPv4-in-IPv6 addresses (e.g., ::ffff:192.0.2.1) +// as input. The methods do not perform automatic unmapping to avoid unnecessary +// overhead for the common case where native addresses are used. +// Users should unmap IPv4-in-IPv6 addresses to their native IPv4 form +// (e.g., 192.0.2.1) before calling these methods. +type Fast[V any] struct { + // used by -copylocks checker from `go vet`. + _ [0]sync.Mutex + + // the root nodes, implemented as popcount compressed multibit tries + root4 nodes.FastNode[V] + root6 nodes.FastNode[V] + + // the number of prefixes in the routing table + size4 int + size6 int +} + +// rootNodeByVersion, root node getter for ip version. +func (f *Fast[V]) rootNodeByVersion(is4 bool) *nodes.FastNode[V] { + if is4 { + return &f.root4 + } + return &f.root6 +} + +// Insert adds or updates a prefix-value pair in the routing table. +// If the prefix already exists, its value is updated; otherwise a new entry is created. +// Invalid prefixes are silently ignored. +// +// The prefix is automatically canonicalized using pfx.Masked() to ensure +// consistent behavior regardless of host bits in the input. +func (f *Fast[V]) Insert(pfx netip.Prefix, val V) { + f.insert(pfx, val) +} + +// InsertPersist is similar to Insert but the receiver isn't modified. +// +// All nodes touched during insert are cloned and a new Fast is returned. +// This is not a full [Fast.Clone], all untouched nodes are still referenced +// from both Fasts. +// +// If the payload type V contains pointers or needs deep copying, +// it must implement the Clone method to support correct cloning. +// +// Due to cloning overhead this is significantly slower than Insert, +// typically taking μsec instead of nsec. +func (f *Fast[V]) InsertPersist(pfx netip.Prefix, val V) *Fast[V] { + return f.insertPersist(pfx, val) +} + +// Modify applies an insert, update, or delete operation for the value +// associated with the given prefix. The supplied callback decides the +// operation: it is called with the current value (or zero if not found) +// and a boolean indicating whether the prefix exists. The callback must +// return a new value and a delete flag: del == false inserts or updates, +// del == true deletes the entry if it exists (otherwise no-op). +// +// The callback is invoked at most once per call. +// +// The operation is determined by the callback function, which is called with: +// +// val: the current value (or zero value if not found) +// found: true if the prefix currently exists, false otherwise +// +// The callback returns: +// +// val: the new value to insert or update (ignored if del == true) +// del: true to delete the entry, false to insert or update +// +// Summary of callback semantics: +// +// | cb-input | cb-return | Ops | +// |-----------------|-----------------|--------| +// | (zero, false) | (_, true) | no-op | +// | (zero, false) | (newVal, false) | insert | +// | (oldVal, true) | (newVal, false) | update | +// | (oldVal, true) | (_, true) | delete | +// ------------------------------------- -------- +func (f *Fast[V]) Modify(pfx netip.Prefix, cb func(_ V, ok bool) (_ V, del bool)) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + + n := f.rootNodeByVersion(is4) + + delta := n.Modify(pfx, cb) + f.sizeUpdate(is4, delta) +} + +// Contains reports whether any stored prefix covers the given IP address. +// Returns false for invalid IP addresses. +// +// This performs longest-prefix matching and returns true if any prefix +// in the routing table contains the IP address, regardless of the associated value. +// +// It does not return the value or the prefix of the matching item, +// but as a test against an allow-/deny-list it's often sufficient +// and even few nanoseconds faster than [Fast.Lookup]. +func (f *Fast[V]) Contains(ip netip.Addr) bool { + // speed is top priority: no explicit test for ip.IsValid + // if ip is invalid, AsSlice() returns nil, Contains returns false. + is4 := ip.Is4() + n := f.rootNodeByVersion(is4) + + for _, octet := range ip.AsSlice() { + // for contains, any lpm match is good enough, no backtracking needed + if n.PrefixCount() != 0 && n.Contains(art.OctetToIdx(octet)) { + return true + } + + // stop traversing? + if !n.Children.Test(octet) { + return false + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *nodes.FastNode[V]: + n = kid // descend down to next trie level + + case *nodes.FringeNode[V]: + // fringe is the default-route for all possible octets below + return true + + case *nodes.LeafNode[V]: + return kid.Prefix.Contains(ip) + } + } + + return false +} + +// Lookup performs a longest prefix match (LPM) lookup for the given address. +// It finds the most specific (longest) prefix in the routing table that +// contains the given address and returns its associated value. +// +// This is the fundamental operation for IP routing decisions, finding the +// best matching route for a destination address. +// +// Returns the associated value and true if a matching prefix is found. +// Returns zero value and false if no prefix contains the address. +func (f *Fast[V]) Lookup(ip netip.Addr) (val V, ok bool) { + if !ip.IsValid() { + return val, ok + } + + is4 := ip.Is4() + octets := ip.AsSlice() + + n := f.rootNodeByVersion(is4) + + // stack of the traversed nodes for fast backtracking, if needed + stack := [nodes.MaxTreeDepth]*nodes.FastNode[V]{} + + // run variable, used after for loop + var depth int + var octet byte + +LOOP: + // find leaf node + for depth, octet = range octets { + depth &= nodes.DepthMask // BCE, Lookup must be fast + + // push current node on stack for fast backtracking + stack[depth] = n + + // go down in tight loop to last octet + if !n.Children.Test(octet) { + // no more nodes below octet + break LOOP + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *nodes.FastNode[V]: + n = kid + continue LOOP // descend down to next trie level + + case *nodes.FringeNode[V]: + // fringe is the default-route for all possible octets below + return kid.Value, true + + case *nodes.LeafNode[V]: + if kid.Prefix.Contains(ip) { + return kid.Value, true + } + // reached a path compressed prefix, stop traversing + break LOOP + } + } + + // start backtracking, unwind the stack, bounds check eliminated + for ; depth >= 0; depth-- { + depth &= nodes.DepthMask // BCE + + n = stack[depth] + + // longest prefix match, skip if node has no prefixes + if n.PrefixCount() != 0 { + idx := art.OctetToIdx(octets[depth]) + // lookupIdx() manually inlined + if lpmIdx, ok2 := n.Prefixes.IntersectionTop(&lpm.LookupTbl[idx]); ok2 { + return n.MustGetPrefix(lpmIdx), ok2 + } + } + } + + return val, ok +} + +// LookupPrefix performs a longest prefix match lookup for any address within +// the given prefix. It finds the most specific routing table entry that would +// match any address in the provided prefix range. +// +// This is functionally identical to LookupPrefixLPM but returns only the +// associated value, not the matching prefix itself. +// +// Returns the value and true if a matching prefix is found. +// Returns zero value and false if no match exists. +func (f *Fast[V]) LookupPrefix(pfx netip.Prefix) (val V, ok bool) { + _, val, ok = f.lookupPrefixLPM(pfx, false) + return val, ok +} + +// LookupPrefixLPM performs a longest prefix match lookup for any address within +// the given prefix. It finds the most specific routing table entry that would +// match any address in the provided prefix range. +// +// This is functionally identical to LookupPrefix but additionally returns the +// matching LPM prefix itself along with the value. +// +// This method is slower than LookupPrefix and should only be used if the +// matching lpm entry is also required for other reasons. +// +// Returns the matching prefix, its associated value, and true if found. +// Returns zero values and false if no match exists. +func (f *Fast[V]) LookupPrefixLPM(pfx netip.Prefix) (lpmPfx netip.Prefix, val V, ok bool) { + return f.lookupPrefixLPM(pfx, true) +} + +func (f *Fast[V]) lookupPrefixLPM(pfx netip.Prefix, withLPM bool) (lpmPfx netip.Prefix, val V, ok bool) { + if !pfx.IsValid() { + return lpmPfx, val, ok + } + + // canonicalize the prefix + pfx = pfx.Masked() + + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := nodes.DivMod8(pfxLen) + + n := f.rootNodeByVersion(is4) + + // record path to leaf node + stack := [nodes.MaxTreeDepth]*nodes.FastNode[V]{} + + var depth int + var octet byte + +LOOP: + // find the last node on the octets path in the trie, + for depth, octet = range octets { + depth &= nodes.DepthMask // BCE + + // stepped one past the last stride of interest; back up to last and break + if depth > strideCount { + depth-- + break + } + // push current node on stack + stack[depth] = n + + // go down in tight loop to leaf node + if !n.Children.Test(octet) { + break LOOP + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *nodes.FastNode[V]: + n = kid + continue LOOP // descend down to next trie level + + case *nodes.LeafNode[V]: + // reached a path compressed prefix, stop traversing + if kid.Prefix.Bits() > pfxLen || !kid.Prefix.Contains(ip) { + break LOOP + } + return kid.Prefix, kid.Value, true + + case *nodes.FringeNode[V]: + // the bits of the fringe are defined by the depth + // maybe the LPM isn't needed, saves some cycles + fringeBits := (depth + 1) << 3 + if fringeBits > pfxLen { + break LOOP + } + + // the LPM isn't needed, saves some cycles + if !withLPM { + return netip.Prefix{}, kid.Value, true + } + + // get the LPM prefix back from ip and depth + // it's a fringe, bits are always /8, /16, /24, ... + fringePfx, _ := ip.Prefix((depth + 1) << 3) + return fringePfx, kid.Value, true + } + } + + // start backtracking, unwind the stack + for ; depth >= 0; depth-- { + depth &= nodes.DepthMask // BCE + + n = stack[depth] + + // longest prefix match, skip if node has no prefixes + if n.Prefixes.Len() == 0 { + continue + } + + var idx uint8 + octet = octets[depth] + + // only the final stride may have a different prefix len + // all others are just host routes + if depth == strideCount { + idx = art.PfxToIdx(octet, modBits) + } else { + idx = art.OctetToIdx(octet) + } + + // manually inlined: lookupIdx(idx) + var topIdx uint8 + if topIdx, ok = n.Prefixes.IntersectionTop(&lpm.LookupTbl[idx]); ok { + val = n.MustGetPrefix(topIdx) + + // called from LookupPrefix + if !withLPM { + return netip.Prefix{}, val, ok + } + + // called from LookupPrefixLPM + + // get the bits from depth and top idx + pfxBits := int(art.PfxBits(depth, topIdx)) + + // calculate the lpmPfx from incoming ip and new mask + // netip.Addr.Prefix canonicalizes. Invariant: art.PfxBits(depth, topIdx) + // yields a valid mask (v4: 0..32, v6: 0..128), so error is impossible. + lpmPfx, _ = ip.Prefix(pfxBits) + return lpmPfx, val, ok + } + } + + return lpmPfx, val, ok +} diff --git a/vendor/github.com/gaissmai/bart/fastmethodsgenerated.go b/vendor/github.com/gaissmai/bart/fastmethodsgenerated.go new file mode 100644 index 0000000..c6521b0 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/fastmethodsgenerated.go @@ -0,0 +1,731 @@ +// Code generated from file "commonmethods_tmpl.go"; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package bart + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "iter" + "net/netip" + "slices" + "strings" + + "github.com/gaissmai/bart/internal/nodes" + "github.com/gaissmai/bart/internal/value" +) + +func (t *Fast[V]) sizeUpdate(is4 bool, delta int) { + if is4 { + t.size4 += delta + return + } + t.size6 += delta +} + +// insert adds or updates a prefix-value pair in the routing table. +// If the prefix already exists, its value is updated; otherwise a new entry is created. +// Invalid prefixes are silently ignored. +// +// The prefix is automatically canonicalized using pfx.Masked() to ensure +// consistent behavior regardless of host bits in the input. +func (t *Fast[V]) insert(pfx netip.Prefix, val V) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + if exists := n.Insert(pfx, val, 0); exists { + return + } + + // true insert, update size + t.sizeUpdate(is4, 1) +} + +// insertPersist is similar to insert but the receiver isn't modified. +// +// All nodes touched during insert are cloned and a new Fast is returned. +// This is not a full [Fast.Clone], all untouched nodes are still referenced +// from both Tables. +// +// If the payload type V contains pointers or needs deep copying, +// implement: +// +// func (v V) Clone() V +// +// The bart package detects this via structural typing and deep‑copies +// values during persistent ops. +// +// Due to cloning overhead this is significantly slower than insert, +// typically taking μsec instead of nsec. +func (t *Fast[V]) insertPersist(pfx netip.Prefix, val V) *Fast[V] { + if !pfx.IsValid() { + return t + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + // share size counters; root nodes cloned selectively. + pt := &Fast[V]{ + size4: t.size4, + size6: t.size6, + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // Clone root node corresponding to the IP version, for copy-on-write. + n := &pt.root4 + + if is4 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + pt.root6 = t.root6 + } else { + pt.root4 = t.root4 + pt.root6 = *t.root6.CloneFlat(cloneFn) + + n = &pt.root6 + } + + if !n.InsertPersist(cloneFn, pfx, val, 0) { + pt.sizeUpdate(is4, 1) + } + + return pt +} + +// Delete removes the exact prefix pfx from the table in-place. +// +// This is an exact-match operation (no LPM). If pfx exists, the entry is +// removed. If pfx does not exist or pfx is invalid, the table is left unchanged. +// +// The prefix is canonicalized (Masked) before lookup. +func (t *Fast[V]) Delete(pfx netip.Prefix) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + if exists := n.Delete(pfx); exists { + t.sizeUpdate(is4, -1) + } +} + +// Get performs an exact-prefix lookup and returns whether the exact +// prefix exists. The prefix is canonicalized (Masked) before lookup. +// +// This is an exact-match operation (no LPM). The prefix must match exactly +// in both address and prefix length to be found. If pfx exists, the +// associated value (zero value for Lite) and found=true is returned. +// If pfx does not exist or pfx is invalid, the zero value for V and +// exists=false is returned. +// +// For longest-prefix-match (LPM) lookups, use Contains(ip), Lookup(ip), +// LookupPrefix(pfx) or LookupPrefixLPM(pfx) instead. +func (t *Fast[V]) Get(pfx netip.Prefix) (val V, exists bool) { + if !pfx.IsValid() { + return val, exists + } + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + return n.Get(pfx) +} + +// DeletePersist is similar to Delete but does not modify the receiver. +// +// It performs a copy-on-write delete operation, cloning all nodes touched during +// deletion and returning a new Fast reflecting the change. +// +// If the prefix is invalid or doesn't exist, the original table is +// returned unchanged. +// +// If the payload type V contains pointers or requires deep copying, +// it must implement the Clone method for correct cloning. +// +// Due to cloning overhead this is significantly slower than Delete, +// typically taking μsec instead of nsec. +func (t *Fast[V]) DeletePersist(pfx netip.Prefix) *Fast[V] { + if !pfx.IsValid() { + return t + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + // Preflight check: avoid cloning if prefix doesn't exist + n := t.rootNodeByVersion(is4) + if _, found := n.Get(pfx); !found { + return t + } + + // share size counters; root nodes cloned selectively. + pt := &Fast[V]{ + size4: t.size4, + size6: t.size6, + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // Clone root node corresponding to the IP version, for copy-on-write. + if is4 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + pt.root6 = t.root6 + n = &pt.root4 + } else { + pt.root4 = t.root4 + pt.root6 = *t.root6.CloneFlat(cloneFn) + n = &pt.root6 + } + + if exists := n.DeletePersist(cloneFn, pfx); exists { + pt.sizeUpdate(is4, -1) + } + + return pt +} + +// ModifyPersist is similar to Modify but the receiver isn't modified and +// a new *Fast is returned. +func (t *Fast[V]) ModifyPersist(pfx netip.Prefix, cb func(_ V, ok bool) (_ V, del bool)) *Fast[V] { + if !pfx.IsValid() { + return t + } + + // make a cheap test in front of expensive operation + oldVal, ok := t.Get(pfx) + val := oldVal + + // to clone or not to clone ... + cloneFn := value.CloneFnFactory[V]() + if cloneFn != nil && ok { + val = cloneFn(oldVal) + } + + newVal, del := cb(val, ok) + + switch { + case !ok && del: // no-op + return t + + case !ok && !del: // insert + return t.InsertPersist(pfx, newVal) + + case ok && !del: // update + return t.InsertPersist(pfx, newVal) + + case ok && del: // delete + return t.DeletePersist(pfx) + } + + panic("unreachable") +} + +// Supernets returns an iterator over all supernet routes that cover the given prefix pfx. +// +// The traversal searches both exact-length and shorter (less specific) prefixes that +// include pfx. Starting from the most specific position in the trie, +// it walks upward through parent nodes and yields any matching entries found at each level. +// +// The iteration order is reverse-CIDR: from longest prefix match (LPM) towards +// least-specific routes. +// +// This can be used to enumerate all covering supernet routes in routing-based +// policy engines, diagnostics tools, or fallback resolution logic. +// +// Example: +// +// for supernet, val := range table.Supernets(netip.MustParsePrefix("192.0.2.128/25")) { +// fmt.Println("Covered by:", supernet, "->", val) +// } +// +// The iteration can be stopped early by breaking from the range loop. +// Returns an empty iterator if the prefix is invalid. +func (t *Fast[V]) Supernets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if !pfx.IsValid() { + return + } + + // canonicalize the prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + n.Supernets(pfx, yield) + } +} + +// Subnets returns an iterator over all subnets of the given prefix +// in natural CIDR sort order. This includes prefixes of the same length +// (exact match) and longer (more specific) prefixes that are contained +// within the given prefix. +// +// Example: +// +// for sub, val := range table.Subnets(netip.MustParsePrefix("10.0.0.0/8")) { +// fmt.Println("Covered:", sub, "->", val) +// } +// +// The iteration can be stopped early by breaking from the range loop. +// Returns an empty iterator if the prefix is invalid. +func (t *Fast[V]) Subnets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if !pfx.IsValid() { + return + } + + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + n.Subnets(pfx, yield) + } +} + +// OverlapsPrefix reports whether any prefix in the routing table overlaps with +// the given prefix. Two prefixes overlap if they share any IP addresses. +// +// The check is bidirectional: it returns true if the input prefix is covered by an existing +// route, or if any stored route is itself contained within the input prefix. +// +// Internally, the function normalizes the prefix and descends the relevant trie branch, +// using stride-based logic to identify overlap without performing a full lookup. +// +// This is useful for containment tests, route validation, or policy checks using prefix +// semantics without retrieving exact matches. +func (t *Fast[V]) OverlapsPrefix(pfx netip.Prefix) bool { + if !pfx.IsValid() { + return false + } + + // canonicalize the prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + return n.OverlapsPrefixAtDepth(pfx, 0) +} + +// Overlaps reports whether any route in the receiver table overlaps +// with a route in the other table, in either direction. +// +// The overlap check is bidirectional: it returns true if any IP prefix +// in the receiver is covered by the other table, or vice versa. +// This includes partial overlaps, exact matches, and supernet/subnet relationships. +// +// Both IPv4 and IPv6 route trees are compared independently. If either +// tree has overlapping routes, the function returns true. +// +// This is useful for conflict detection, policy enforcement, +// or validating mutually exclusive routing domains. +func (t *Fast[V]) Overlaps(o *Fast[V]) bool { + return t.Overlaps4(o) || t.Overlaps6(o) +} + +// Overlaps4 is like [Fast.Overlaps] but for the v4 routing table only. +func (t *Fast[V]) Overlaps4(o *Fast[V]) bool { + if t.size4 == 0 || o.size4 == 0 { + return false + } + return t.root4.Overlaps(&o.root4, 0) +} + +// Overlaps6 is like [Fast.Overlaps] but for the v6 routing table only. +func (t *Fast[V]) Overlaps6(o *Fast[V]) bool { + if t.size6 == 0 || o.size6 == 0 { + return false + } + return t.root6.Overlaps(&o.root6, 0) +} + +// Union merges another routing table into the receiver table, modifying it in-place. +// +// All prefixes and values from the other table (o) are inserted into the receiver. +// If a duplicate prefix exists in both tables, the value from o replaces the existing entry. +// This duplicate is shallow-copied by default, but if the value type V implements the +// Clone method, the value is deeply cloned before insertion. See also Fast.Clone. +func (t *Fast[V]) Union(o *Fast[V]) { + // panics on nil receiver + _ = t.size4 + + // panics on nil argument + if o.size4 == 0 && o.size6 == 0 { + return + } + // t is unchanged + if o == t { + return + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + dup4 := t.root4.UnionRec(cloneFn, &o.root4, 0) + dup6 := t.root6.UnionRec(cloneFn, &o.root6, 0) + + t.size4 += o.size4 - dup4 + t.size6 += o.size6 - dup6 +} + +// UnionPersist is similar to [Union] but the receiver isn't modified. +// +// All nodes touched during union are cloned and a new *Fast is returned. +// If o is empty, no nodes are touched and the receiver may be +// returned unchanged. +func (t *Fast[V]) UnionPersist(o *Fast[V]) *Fast[V] { + // panics on nil receiver + _ = t.size4 + + // panics on nil argument + if o.size4 == 0 && o.size6 == 0 { + return t + } + if o == t { + return t + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // new Fast with root nodes just copied. + pt := &Fast[V]{ + root4: t.root4, + root6: t.root6, + // + size4: t.size4, + size6: t.size6, + } + + // only clone the root node if there is something to union + if o.size4 != 0 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + } + if o.size6 != 0 { + pt.root6 = *t.root6.CloneFlat(cloneFn) + } + + dup4 := pt.root4.UnionRecPersist(cloneFn, &o.root4, 0) + dup6 := pt.root6.UnionRecPersist(cloneFn, &o.root6, 0) + + pt.size4 += o.size4 - dup4 + pt.size6 += o.size6 - dup6 + + return pt +} + +// Equal checks whether two tables are structurally and semantically equal. +// It ensures both trees (IPv4-based and IPv6-based) have the same sizes and +// recursively compares their root nodes. +// +// If V implements an `Equal(V) bool` method, its custom equality logic is used. +// Otherwise, values are compared directly using the == operator. +// +// Note: If V implements `Equal(V) bool` with a pointer receiver, the Equal +// method should handle nil receivers gracefully. +// +// ATTENTION: If V is not comparable at runtime (such as a slice or map without an `Equal` +// method), a runtime panic will occur. +func (t *Fast[V]) Equal(o *Fast[V]) bool { + if t.size4 != o.size4 || t.size6 != o.size6 { + return false + } + if o == t { + return true + } + + return t.root4.EqualRec(&o.root4) && t.root6.EqualRec(&o.root6) +} + +// Clone returns a copy of the routing table. +// The payload of type V is shallow copied by default. To enable deep copying, +// implement the following method on your value type: +// +// Clone() V +// +// Example: +// +// type MyValue struct { Data []byte } +// func (v MyValue) Clone() MyValue { +// return MyValue{Data: slices.Clone(v.Data)} +// } +// +// The bart package will automatically detect and use this method via Go's +// structural typing. +// +// Note: If V implements Clone() V with a pointer receiver, the Clone +// method should handle nil receivers gracefully. +func (t *Fast[V]) Clone() *Fast[V] { + c := new(Fast[V]) + + cloneFn := value.CloneFnFactory[V]() + + c.root4 = *t.root4.CloneRec(cloneFn) + c.root6 = *t.root6.CloneRec(cloneFn) + + c.size4 = t.size4 + c.size6 = t.size6 + + return c +} + +// Size returns the prefix count. +func (t *Fast[V]) Size() int { + return t.size4 + t.size6 +} + +// Size4 returns the IPv4 prefix count. +func (t *Fast[V]) Size4() int { + return t.size4 +} + +// Size6 returns the IPv6 prefix count. +func (t *Fast[V]) Size6() int { + return t.size6 +} + +// All returns an iterator over all prefix–value pairs in the table. +// +// The iteration order is unspecified and may vary between calls; for a stable order, +// use [Fast.AllSorted]. +// +// IMPORTANT: Modifying the table during iteration is not allowed, +// as this would interfere with the internal traversal and may corrupt or +// prematurely terminate the iteration. +func (t *Fast[V]) All() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRec(stridePath{}, 0, true, yield) && t.root6.AllRec(stridePath{}, 0, false, yield) + } +} + +// All4 is like [Fast.All] but only for the v4 routing table. +func (t *Fast[V]) All4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRec(stridePath{}, 0, true, yield) + } +} + +// All6 is like [Fast.All] but only for the v6 routing table. +func (t *Fast[V]) All6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root6.AllRec(stridePath{}, 0, false, yield) + } +} + +// AllSorted is like [Fast.All] but the iteration is ordered in canonical +// CIDR prefix sort order. +func (t *Fast[V]) AllSorted() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRecSorted(stridePath{}, 0, true, yield) && + t.root6.AllRecSorted(stridePath{}, 0, false, yield) + } +} + +// AllSorted4 is like [Fast.AllSorted] but only for the v4 routing table. +func (t *Fast[V]) AllSorted4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRecSorted(stridePath{}, 0, true, yield) + } +} + +// AllSorted6 is like [Fast.AllSorted] but only for the v6 routing table. +func (t *Fast[V]) AllSorted6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root6.AllRecSorted(stridePath{}, 0, false, yield) + } +} + +// Fprint writes a hierarchical tree diagram of the ordered CIDRs +// with default formatted payload V to w. +// +// The order from top to bottom is in ascending order of the prefix address +// and the subtree structure is determined by the CIDRs coverage. +// +// ▼ +// ├─ 10.0.0.0/8 (V) +// │ ├─ 10.0.0.0/24 (V) +// │ └─ 10.0.1.0/24 (V) +// ├─ 127.0.0.0/8 (V) +// │ └─ 127.0.0.1/32 (V) +// ├─ 169.254.0.0/16 (V) +// ├─ 172.16.0.0/12 (V) +// └─ 192.168.0.0/16 (V) +// └─ 192.168.1.0/24 (V) +// ▼ +// └─ ::/0 (V) +// ├─ ::1/128 (V) +// ├─ 2000::/3 (V) +// │ └─ 2001:db8::/32 (V) +// └─ fe80::/10 (V) +func (t *Fast[V]) Fprint(w io.Writer) error { + if w == nil && t != nil { + return fmt.Errorf("nil writer") + } + + // v4 + if err := t.fprint(w, true); err != nil { + return err + } + + // v6 + if err := t.fprint(w, false); err != nil { + return err + } + + return nil +} + +// fprint is the version dependent adapter to fprintRec. +func (t *Fast[V]) fprint(w io.Writer, is4 bool) error { + n := t.rootNodeByVersion(is4) + if n.IsEmpty() { + return nil + } + + if _, err := fmt.Fprint(w, "▼\n"); err != nil { + return err + } + + startParent := nodes.TrieItem[V]{ + Node: nil, + Idx: 0, + Path: stridePath{}, + Is4: is4, + } + + return n.FprintRec(w, startParent, "") +} + +// MarshalText implements the [encoding.TextMarshaler] interface, +// just a wrapper for [Fast.Fprint]. +func (t *Fast[V]) MarshalText() ([]byte, error) { + w := new(bytes.Buffer) + if err := t.Fprint(w); err != nil { + return nil, err + } + + return w.Bytes(), nil +} + +// MarshalJSON dumps the table into two sorted lists: for ipv4 and ipv6. +// Every root and subnet is an array, not a map, because the order matters. +func (t *Fast[V]) MarshalJSON() ([]byte, error) { + result := struct { + Ipv4 []DumpListNode[V] `json:"ipv4,omitempty"` + Ipv6 []DumpListNode[V] `json:"ipv6,omitempty"` + }{ + Ipv4: t.DumpList4(), + Ipv6: t.DumpList6(), + } + + buf, err := json.Marshal(result) + if err != nil { + return nil, err + } + + return buf, nil +} + +// DumpList4 dumps the ipv4 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build the text or JSON serialization. +func (t *Fast[V]) DumpList4() []DumpListNode[V] { + return t.dumpListRec(&t.root4, 0, stridePath{}, 0, true) +} + +// DumpList6 dumps the ipv6 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build custom JSON representation. +func (t *Fast[V]) DumpList6() []DumpListNode[V] { + return t.dumpListRec(&t.root6, 0, stridePath{}, 0, false) +} + +// dumpListRec, build the data structure rec-descent with the help of directItemsRec. +// anyNode is nodes.BartNode, nodes.FastNode or nodes.LiteNode +func (t *Fast[V]) dumpListRec(anyNode any, parentIdx uint8, path stridePath, depth int, is4 bool) []DumpListNode[V] { + // recursion stop condition + if anyNode == nil { + return nil + } + + // the same method is generated for all table types, therefore + // type assert to the smallest needed interface. + // The panic on wrong type assertion is by intention, MUST NOT happen + n := anyNode.(interface { + DirectItemsRec(uint8, stridePath, int, bool) []nodes.TrieItem[V] + }) + + directItems := n.DirectItemsRec(parentIdx, path, depth, is4) + + // sort the items by prefix + slices.SortFunc(directItems, func(a, b nodes.TrieItem[V]) int { + return nodes.CmpPrefix(a.Cidr, b.Cidr) + }) + + dumpNodes := make([]DumpListNode[V], 0, len(directItems)) + + for _, item := range directItems { + dumpNodes = append(dumpNodes, DumpListNode[V]{ + CIDR: item.Cidr, + Value: item.Val, + // build it rec-descent, item.Node is also from type any + Subnets: t.dumpListRec(item.Node, item.Idx, item.Path, item.Depth, is4), + }) + } + + return dumpNodes +} + +// dumpString is just a wrapper for dump. +func (t *Fast[V]) dumpString() string { + w := new(strings.Builder) + t.dump(w) + + return w.String() +} + +// dump the table structure and all the nodes to w. +func (t *Fast[V]) dump(w io.Writer) { + if t.size4 > 0 { + stats := t.root4.StatsRec() + fmt.Fprintln(w) + fmt.Fprintf(w, "### IPv4: size(%d), subnodes(%d), prefixes(%d), leaves(%d), fringes(%d)", + t.size4, stats.SubNodes, stats.Prefixes, stats.Leaves, stats.Fringes) + + t.root4.DumpRec(w, stridePath{}, 0, true) + } + + if t.size6 > 0 { + stats := t.root6.StatsRec() + fmt.Fprintln(w) + fmt.Fprintf(w, "### IPv6: size(%d), subnodes(%d), prefixes(%d), leaves(%d), fringes(%d)", + t.size6, stats.SubNodes, stats.Prefixes, stats.Leaves, stats.Fringes) + + t.root6.DumpRec(w, stridePath{}, 0, false) + } +} diff --git a/vendor/github.com/gaissmai/bart/internal/allot/allotroutesgenerated.go b/vendor/github.com/gaissmai/bart/internal/allot/allotroutesgenerated.go new file mode 100644 index 0000000..3ae9285 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/allot/allotroutesgenerated.go @@ -0,0 +1,547 @@ +// Code generated by generate_allottbl.go; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package allot + +import "github.com/gaissmai/bart/internal/bitset" + +// PfxRoutesLookupTbl is a lookup table of BitSet256 entries. +// +// It maps a baseIndex (1..255) to a bitset that contains all more +// specific baseIndices that are covered by the prefix at that index. +// +// The idea: +// +// If prefix P has baseIndex idx, then P covers all prefixes in the subtree +// rooted at idx. This table enumerates and encodes those indices. +// +// The table is split: +// - PfxRoutesLookupTbl holds prefixes up to /7 +// - FringeRoutesLookupTbl holds /8 prefixes +// +// This structure allows for very fast set inclusion checks using simple bitwise AND. +// +//nolint:gochecknoglobals // Precomputed read‑only table used in hot paths. +var PfxRoutesLookupTbl = [256]bitset.BitSet256{ + /* idx: 0 */ {0x0, 0x0, 0x0, 0x0}, // invalid + /* idx: 1 */ {0xfffffffffffffffe, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}, // [1, 2, 3, 4, 5, ... ] + /* idx: 2 */ {0xffff00ff0f34, 0xffffffff, 0xffffffffffffffff, 0x0}, // [2, 4, 5, 8, 9, ... ] + /* idx: 3 */ {0xffff0000ff00f0c8, 0xffffffff00000000, 0x0, 0xffffffffffffffff}, // [3, 6, 7, 12, 13, ... ] + /* idx: 4 */ {0xff000f0310, 0xffff, 0xffffffff, 0x0}, // [4, 8, 9, 16, 17, ... ] + /* idx: 5 */ {0xff0000f00c20, 0xffff0000, 0xffffffff00000000, 0x0}, // [5, 10, 11, 20, 21, ... ] + /* idx: 6 */ {0xff00000f003040, 0xffff00000000, 0x0, 0xffffffff}, // [6, 12, 13, 24, 25, ... ] + /* idx: 7 */ {0xff000000f000c080, 0xffff000000000000, 0x0, 0xffffffff00000000}, // [7, 14, 15, 28, 29, ... ] + /* idx: 8 */ {0xf00030100, 0xff, 0xffff, 0x0}, // [8, 16, 17, 32, 33, ... ] + /* idx: 9 */ {0xf0000c0200, 0xff00, 0xffff0000, 0x0}, // [9, 18, 19, 36, 37, ... ] + /* idx: 10 */ {0xf0000300400, 0xff0000, 0xffff00000000, 0x0}, // [10, 20, 21, 40, 41, ... ] + /* idx: 11 */ {0xf00000c00800, 0xff000000, 0xffff000000000000, 0x0}, // [11, 22, 23, 44, 45, ... ] + /* idx: 12 */ {0xf000003001000, 0xff00000000, 0x0, 0xffff}, // [12, 24, 25, 48, 49, ... ] + /* idx: 13 */ {0xf000000c002000, 0xff0000000000, 0x0, 0xffff0000}, // [13, 26, 27, 52, 53, ... ] + /* idx: 14 */ {0xf00000030004000, 0xff000000000000, 0x0, 0xffff00000000}, // [14, 28, 29, 56, 57, ... ] + /* idx: 15 */ {0xf0000000c0008000, 0xff00000000000000, 0x0, 0xffff000000000000}, // [15, 30, 31, 60, 61, ... ] + /* idx: 16 */ {0x300010000, 0xf, 0xff, 0x0}, // [16, 32, 33, 64, 65, ... ] + /* idx: 17 */ {0xc00020000, 0xf0, 0xff00, 0x0}, // [17, 34, 35, 68, 69, ... ] + /* idx: 18 */ {0x3000040000, 0xf00, 0xff0000, 0x0}, // [18, 36, 37, 72, 73, ... ] + /* idx: 19 */ {0xc000080000, 0xf000, 0xff000000, 0x0}, // [19, 38, 39, 76, 77, ... ] + /* idx: 20 */ {0x30000100000, 0xf0000, 0xff00000000, 0x0}, // [20, 40, 41, 80, 81, ... ] + /* idx: 21 */ {0xc0000200000, 0xf00000, 0xff0000000000, 0x0}, // [21, 42, 43, 84, 85, ... ] + /* idx: 22 */ {0x300000400000, 0xf000000, 0xff000000000000, 0x0}, // [22, 44, 45, 88, 89, ... ] + /* idx: 23 */ {0xc00000800000, 0xf0000000, 0xff00000000000000, 0x0}, // [23, 46, 47, 92, 93, ... ] + /* idx: 24 */ {0x3000001000000, 0xf00000000, 0x0, 0xff}, // [24, 48, 49, 96, 97, ... ] + /* idx: 25 */ {0xc000002000000, 0xf000000000, 0x0, 0xff00}, // [25, 50, 51, 100, 101, ... ] + /* idx: 26 */ {0x30000004000000, 0xf0000000000, 0x0, 0xff0000}, // [26, 52, 53, 104, 105, ... ] + /* idx: 27 */ {0xc0000008000000, 0xf00000000000, 0x0, 0xff000000}, // [27, 54, 55, 108, 109, ... ] + /* idx: 28 */ {0x300000010000000, 0xf000000000000, 0x0, 0xff00000000}, // [28, 56, 57, 112, 113, ... ] + /* idx: 29 */ {0xc00000020000000, 0xf0000000000000, 0x0, 0xff0000000000}, // [29, 58, 59, 116, 117, ... ] + /* idx: 30 */ {0x3000000040000000, 0xf00000000000000, 0x0, 0xff000000000000}, // [30, 60, 61, 120, 121, ... ] + /* idx: 31 */ {0xc000000080000000, 0xf000000000000000, 0x0, 0xff00000000000000}, // [31, 62, 63, 124, 125, ... ] + /* idx: 32 */ {0x100000000, 0x3, 0xf, 0x0}, // [32 64 65 128 129 130 131] + /* idx: 33 */ {0x200000000, 0xc, 0xf0, 0x0}, // [33 66 67 132 133 134 135] + /* idx: 34 */ {0x400000000, 0x30, 0xf00, 0x0}, // [34 68 69 136 137 138 139] + /* idx: 35 */ {0x800000000, 0xc0, 0xf000, 0x0}, // [35 70 71 140 141 142 143] + /* idx: 36 */ {0x1000000000, 0x300, 0xf0000, 0x0}, // [36 72 73 144 145 146 147] + /* idx: 37 */ {0x2000000000, 0xc00, 0xf00000, 0x0}, // [37 74 75 148 149 150 151] + /* idx: 38 */ {0x4000000000, 0x3000, 0xf000000, 0x0}, // [38 76 77 152 153 154 155] + /* idx: 39 */ {0x8000000000, 0xc000, 0xf0000000, 0x0}, // [39 78 79 156 157 158 159] + /* idx: 40 */ {0x10000000000, 0x30000, 0xf00000000, 0x0}, // [40 80 81 160 161 162 163] + /* idx: 41 */ {0x20000000000, 0xc0000, 0xf000000000, 0x0}, // [41 82 83 164 165 166 167] + /* idx: 42 */ {0x40000000000, 0x300000, 0xf0000000000, 0x0}, // [42 84 85 168 169 170 171] + /* idx: 43 */ {0x80000000000, 0xc00000, 0xf00000000000, 0x0}, // [43 86 87 172 173 174 175] + /* idx: 44 */ {0x100000000000, 0x3000000, 0xf000000000000, 0x0}, // [44 88 89 176 177 178 179] + /* idx: 45 */ {0x200000000000, 0xc000000, 0xf0000000000000, 0x0}, // [45 90 91 180 181 182 183] + /* idx: 46 */ {0x400000000000, 0x30000000, 0xf00000000000000, 0x0}, // [46 92 93 184 185 186 187] + /* idx: 47 */ {0x800000000000, 0xc0000000, 0xf000000000000000, 0x0}, // [47 94 95 188 189 190 191] + /* idx: 48 */ {0x1000000000000, 0x300000000, 0x0, 0xf}, // [48 96 97 192 193 194 195] + /* idx: 49 */ {0x2000000000000, 0xc00000000, 0x0, 0xf0}, // [49 98 99 196 197 198 199] + /* idx: 50 */ {0x4000000000000, 0x3000000000, 0x0, 0xf00}, // [50 100 101 200 201 202 203] + /* idx: 51 */ {0x8000000000000, 0xc000000000, 0x0, 0xf000}, // [51 102 103 204 205 206 207] + /* idx: 52 */ {0x10000000000000, 0x30000000000, 0x0, 0xf0000}, // [52 104 105 208 209 210 211] + /* idx: 53 */ {0x20000000000000, 0xc0000000000, 0x0, 0xf00000}, // [53 106 107 212 213 214 215] + /* idx: 54 */ {0x40000000000000, 0x300000000000, 0x0, 0xf000000}, // [54 108 109 216 217 218 219] + /* idx: 55 */ {0x80000000000000, 0xc00000000000, 0x0, 0xf0000000}, // [55 110 111 220 221 222 223] + /* idx: 56 */ {0x100000000000000, 0x3000000000000, 0x0, 0xf00000000}, // [56 112 113 224 225 226 227] + /* idx: 57 */ {0x200000000000000, 0xc000000000000, 0x0, 0xf000000000}, // [57 114 115 228 229 230 231] + /* idx: 58 */ {0x400000000000000, 0x30000000000000, 0x0, 0xf0000000000}, // [58 116 117 232 233 234 235] + /* idx: 59 */ {0x800000000000000, 0xc0000000000000, 0x0, 0xf00000000000}, // [59 118 119 236 237 238 239] + /* idx: 60 */ {0x1000000000000000, 0x300000000000000, 0x0, 0xf000000000000}, // [60 120 121 240 241 242 243] + /* idx: 61 */ {0x2000000000000000, 0xc00000000000000, 0x0, 0xf0000000000000}, // [61 122 123 244 245 246 247] + /* idx: 62 */ {0x4000000000000000, 0x3000000000000000, 0x0, 0xf00000000000000}, // [62 124 125 248 249 250 251] + /* idx: 63 */ {0x8000000000000000, 0xc000000000000000, 0x0, 0xf000000000000000}, // [63 126 127 252 253 254 255] + /* idx: 64 */ {0x0, 0x1, 0x3, 0x0}, // [64 128 129] + /* idx: 65 */ {0x0, 0x2, 0xc, 0x0}, // [65 130 131] + /* idx: 66 */ {0x0, 0x4, 0x30, 0x0}, // [66 132 133] + /* idx: 67 */ {0x0, 0x8, 0xc0, 0x0}, // [67 134 135] + /* idx: 68 */ {0x0, 0x10, 0x300, 0x0}, // [68 136 137] + /* idx: 69 */ {0x0, 0x20, 0xc00, 0x0}, // [69 138 139] + /* idx: 70 */ {0x0, 0x40, 0x3000, 0x0}, // [70 140 141] + /* idx: 71 */ {0x0, 0x80, 0xc000, 0x0}, // [71 142 143] + /* idx: 72 */ {0x0, 0x100, 0x30000, 0x0}, // [72 144 145] + /* idx: 73 */ {0x0, 0x200, 0xc0000, 0x0}, // [73 146 147] + /* idx: 74 */ {0x0, 0x400, 0x300000, 0x0}, // [74 148 149] + /* idx: 75 */ {0x0, 0x800, 0xc00000, 0x0}, // [75 150 151] + /* idx: 76 */ {0x0, 0x1000, 0x3000000, 0x0}, // [76 152 153] + /* idx: 77 */ {0x0, 0x2000, 0xc000000, 0x0}, // [77 154 155] + /* idx: 78 */ {0x0, 0x4000, 0x30000000, 0x0}, // [78 156 157] + /* idx: 79 */ {0x0, 0x8000, 0xc0000000, 0x0}, // [79 158 159] + /* idx: 80 */ {0x0, 0x10000, 0x300000000, 0x0}, // [80 160 161] + /* idx: 81 */ {0x0, 0x20000, 0xc00000000, 0x0}, // [81 162 163] + /* idx: 82 */ {0x0, 0x40000, 0x3000000000, 0x0}, // [82 164 165] + /* idx: 83 */ {0x0, 0x80000, 0xc000000000, 0x0}, // [83 166 167] + /* idx: 84 */ {0x0, 0x100000, 0x30000000000, 0x0}, // [84 168 169] + /* idx: 85 */ {0x0, 0x200000, 0xc0000000000, 0x0}, // [85 170 171] + /* idx: 86 */ {0x0, 0x400000, 0x300000000000, 0x0}, // [86 172 173] + /* idx: 87 */ {0x0, 0x800000, 0xc00000000000, 0x0}, // [87 174 175] + /* idx: 88 */ {0x0, 0x1000000, 0x3000000000000, 0x0}, // [88 176 177] + /* idx: 89 */ {0x0, 0x2000000, 0xc000000000000, 0x0}, // [89 178 179] + /* idx: 90 */ {0x0, 0x4000000, 0x30000000000000, 0x0}, // [90 180 181] + /* idx: 91 */ {0x0, 0x8000000, 0xc0000000000000, 0x0}, // [91 182 183] + /* idx: 92 */ {0x0, 0x10000000, 0x300000000000000, 0x0}, // [92 184 185] + /* idx: 93 */ {0x0, 0x20000000, 0xc00000000000000, 0x0}, // [93 186 187] + /* idx: 94 */ {0x0, 0x40000000, 0x3000000000000000, 0x0}, // [94 188 189] + /* idx: 95 */ {0x0, 0x80000000, 0xc000000000000000, 0x0}, // [95 190 191] + /* idx: 96 */ {0x0, 0x100000000, 0x0, 0x3}, // [96 192 193] + /* idx: 97 */ {0x0, 0x200000000, 0x0, 0xc}, // [97 194 195] + /* idx: 98 */ {0x0, 0x400000000, 0x0, 0x30}, // [98 196 197] + /* idx: 99 */ {0x0, 0x800000000, 0x0, 0xc0}, // [99 198 199] + /* idx: 100 */ {0x0, 0x1000000000, 0x0, 0x300}, // [100 200 201] + /* idx: 101 */ {0x0, 0x2000000000, 0x0, 0xc00}, // [101 202 203] + /* idx: 102 */ {0x0, 0x4000000000, 0x0, 0x3000}, // [102 204 205] + /* idx: 103 */ {0x0, 0x8000000000, 0x0, 0xc000}, // [103 206 207] + /* idx: 104 */ {0x0, 0x10000000000, 0x0, 0x30000}, // [104 208 209] + /* idx: 105 */ {0x0, 0x20000000000, 0x0, 0xc0000}, // [105 210 211] + /* idx: 106 */ {0x0, 0x40000000000, 0x0, 0x300000}, // [106 212 213] + /* idx: 107 */ {0x0, 0x80000000000, 0x0, 0xc00000}, // [107 214 215] + /* idx: 108 */ {0x0, 0x100000000000, 0x0, 0x3000000}, // [108 216 217] + /* idx: 109 */ {0x0, 0x200000000000, 0x0, 0xc000000}, // [109 218 219] + /* idx: 110 */ {0x0, 0x400000000000, 0x0, 0x30000000}, // [110 220 221] + /* idx: 111 */ {0x0, 0x800000000000, 0x0, 0xc0000000}, // [111 222 223] + /* idx: 112 */ {0x0, 0x1000000000000, 0x0, 0x300000000}, // [112 224 225] + /* idx: 113 */ {0x0, 0x2000000000000, 0x0, 0xc00000000}, // [113 226 227] + /* idx: 114 */ {0x0, 0x4000000000000, 0x0, 0x3000000000}, // [114 228 229] + /* idx: 115 */ {0x0, 0x8000000000000, 0x0, 0xc000000000}, // [115 230 231] + /* idx: 116 */ {0x0, 0x10000000000000, 0x0, 0x30000000000}, // [116 232 233] + /* idx: 117 */ {0x0, 0x20000000000000, 0x0, 0xc0000000000}, // [117 234 235] + /* idx: 118 */ {0x0, 0x40000000000000, 0x0, 0x300000000000}, // [118 236 237] + /* idx: 119 */ {0x0, 0x80000000000000, 0x0, 0xc00000000000}, // [119 238 239] + /* idx: 120 */ {0x0, 0x100000000000000, 0x0, 0x3000000000000}, // [120 240 241] + /* idx: 121 */ {0x0, 0x200000000000000, 0x0, 0xc000000000000}, // [121 242 243] + /* idx: 122 */ {0x0, 0x400000000000000, 0x0, 0x30000000000000}, // [122 244 245] + /* idx: 123 */ {0x0, 0x800000000000000, 0x0, 0xc0000000000000}, // [123 246 247] + /* idx: 124 */ {0x0, 0x1000000000000000, 0x0, 0x300000000000000}, // [124 248 249] + /* idx: 125 */ {0x0, 0x2000000000000000, 0x0, 0xc00000000000000}, // [125 250 251] + /* idx: 126 */ {0x0, 0x4000000000000000, 0x0, 0x3000000000000000}, // [126 252 253] + /* idx: 127 */ {0x0, 0x8000000000000000, 0x0, 0xc000000000000000}, // [127 254 255] + /* idx: 128 */ {0x0, 0x0, 0x1, 0x0}, // [128] + /* idx: 129 */ {0x0, 0x0, 0x2, 0x0}, // [129] + /* idx: 130 */ {0x0, 0x0, 0x4, 0x0}, // [130] + /* idx: 131 */ {0x0, 0x0, 0x8, 0x0}, // [131] + /* idx: 132 */ {0x0, 0x0, 0x10, 0x0}, // [132] + /* idx: 133 */ {0x0, 0x0, 0x20, 0x0}, // [133] + /* idx: 134 */ {0x0, 0x0, 0x40, 0x0}, // [134] + /* idx: 135 */ {0x0, 0x0, 0x80, 0x0}, // [135] + /* idx: 136 */ {0x0, 0x0, 0x100, 0x0}, // [136] + /* idx: 137 */ {0x0, 0x0, 0x200, 0x0}, // [137] + /* idx: 138 */ {0x0, 0x0, 0x400, 0x0}, // [138] + /* idx: 139 */ {0x0, 0x0, 0x800, 0x0}, // [139] + /* idx: 140 */ {0x0, 0x0, 0x1000, 0x0}, // [140] + /* idx: 141 */ {0x0, 0x0, 0x2000, 0x0}, // [141] + /* idx: 142 */ {0x0, 0x0, 0x4000, 0x0}, // [142] + /* idx: 143 */ {0x0, 0x0, 0x8000, 0x0}, // [143] + /* idx: 144 */ {0x0, 0x0, 0x10000, 0x0}, // [144] + /* idx: 145 */ {0x0, 0x0, 0x20000, 0x0}, // [145] + /* idx: 146 */ {0x0, 0x0, 0x40000, 0x0}, // [146] + /* idx: 147 */ {0x0, 0x0, 0x80000, 0x0}, // [147] + /* idx: 148 */ {0x0, 0x0, 0x100000, 0x0}, // [148] + /* idx: 149 */ {0x0, 0x0, 0x200000, 0x0}, // [149] + /* idx: 150 */ {0x0, 0x0, 0x400000, 0x0}, // [150] + /* idx: 151 */ {0x0, 0x0, 0x800000, 0x0}, // [151] + /* idx: 152 */ {0x0, 0x0, 0x1000000, 0x0}, // [152] + /* idx: 153 */ {0x0, 0x0, 0x2000000, 0x0}, // [153] + /* idx: 154 */ {0x0, 0x0, 0x4000000, 0x0}, // [154] + /* idx: 155 */ {0x0, 0x0, 0x8000000, 0x0}, // [155] + /* idx: 156 */ {0x0, 0x0, 0x10000000, 0x0}, // [156] + /* idx: 157 */ {0x0, 0x0, 0x20000000, 0x0}, // [157] + /* idx: 158 */ {0x0, 0x0, 0x40000000, 0x0}, // [158] + /* idx: 159 */ {0x0, 0x0, 0x80000000, 0x0}, // [159] + /* idx: 160 */ {0x0, 0x0, 0x100000000, 0x0}, // [160] + /* idx: 161 */ {0x0, 0x0, 0x200000000, 0x0}, // [161] + /* idx: 162 */ {0x0, 0x0, 0x400000000, 0x0}, // [162] + /* idx: 163 */ {0x0, 0x0, 0x800000000, 0x0}, // [163] + /* idx: 164 */ {0x0, 0x0, 0x1000000000, 0x0}, // [164] + /* idx: 165 */ {0x0, 0x0, 0x2000000000, 0x0}, // [165] + /* idx: 166 */ {0x0, 0x0, 0x4000000000, 0x0}, // [166] + /* idx: 167 */ {0x0, 0x0, 0x8000000000, 0x0}, // [167] + /* idx: 168 */ {0x0, 0x0, 0x10000000000, 0x0}, // [168] + /* idx: 169 */ {0x0, 0x0, 0x20000000000, 0x0}, // [169] + /* idx: 170 */ {0x0, 0x0, 0x40000000000, 0x0}, // [170] + /* idx: 171 */ {0x0, 0x0, 0x80000000000, 0x0}, // [171] + /* idx: 172 */ {0x0, 0x0, 0x100000000000, 0x0}, // [172] + /* idx: 173 */ {0x0, 0x0, 0x200000000000, 0x0}, // [173] + /* idx: 174 */ {0x0, 0x0, 0x400000000000, 0x0}, // [174] + /* idx: 175 */ {0x0, 0x0, 0x800000000000, 0x0}, // [175] + /* idx: 176 */ {0x0, 0x0, 0x1000000000000, 0x0}, // [176] + /* idx: 177 */ {0x0, 0x0, 0x2000000000000, 0x0}, // [177] + /* idx: 178 */ {0x0, 0x0, 0x4000000000000, 0x0}, // [178] + /* idx: 179 */ {0x0, 0x0, 0x8000000000000, 0x0}, // [179] + /* idx: 180 */ {0x0, 0x0, 0x10000000000000, 0x0}, // [180] + /* idx: 181 */ {0x0, 0x0, 0x20000000000000, 0x0}, // [181] + /* idx: 182 */ {0x0, 0x0, 0x40000000000000, 0x0}, // [182] + /* idx: 183 */ {0x0, 0x0, 0x80000000000000, 0x0}, // [183] + /* idx: 184 */ {0x0, 0x0, 0x100000000000000, 0x0}, // [184] + /* idx: 185 */ {0x0, 0x0, 0x200000000000000, 0x0}, // [185] + /* idx: 186 */ {0x0, 0x0, 0x400000000000000, 0x0}, // [186] + /* idx: 187 */ {0x0, 0x0, 0x800000000000000, 0x0}, // [187] + /* idx: 188 */ {0x0, 0x0, 0x1000000000000000, 0x0}, // [188] + /* idx: 189 */ {0x0, 0x0, 0x2000000000000000, 0x0}, // [189] + /* idx: 190 */ {0x0, 0x0, 0x4000000000000000, 0x0}, // [190] + /* idx: 191 */ {0x0, 0x0, 0x8000000000000000, 0x0}, // [191] + /* idx: 192 */ {0x0, 0x0, 0x0, 0x1}, // [192] + /* idx: 193 */ {0x0, 0x0, 0x0, 0x2}, // [193] + /* idx: 194 */ {0x0, 0x0, 0x0, 0x4}, // [194] + /* idx: 195 */ {0x0, 0x0, 0x0, 0x8}, // [195] + /* idx: 196 */ {0x0, 0x0, 0x0, 0x10}, // [196] + /* idx: 197 */ {0x0, 0x0, 0x0, 0x20}, // [197] + /* idx: 198 */ {0x0, 0x0, 0x0, 0x40}, // [198] + /* idx: 199 */ {0x0, 0x0, 0x0, 0x80}, // [199] + /* idx: 200 */ {0x0, 0x0, 0x0, 0x100}, // [200] + /* idx: 201 */ {0x0, 0x0, 0x0, 0x200}, // [201] + /* idx: 202 */ {0x0, 0x0, 0x0, 0x400}, // [202] + /* idx: 203 */ {0x0, 0x0, 0x0, 0x800}, // [203] + /* idx: 204 */ {0x0, 0x0, 0x0, 0x1000}, // [204] + /* idx: 205 */ {0x0, 0x0, 0x0, 0x2000}, // [205] + /* idx: 206 */ {0x0, 0x0, 0x0, 0x4000}, // [206] + /* idx: 207 */ {0x0, 0x0, 0x0, 0x8000}, // [207] + /* idx: 208 */ {0x0, 0x0, 0x0, 0x10000}, // [208] + /* idx: 209 */ {0x0, 0x0, 0x0, 0x20000}, // [209] + /* idx: 210 */ {0x0, 0x0, 0x0, 0x40000}, // [210] + /* idx: 211 */ {0x0, 0x0, 0x0, 0x80000}, // [211] + /* idx: 212 */ {0x0, 0x0, 0x0, 0x100000}, // [212] + /* idx: 213 */ {0x0, 0x0, 0x0, 0x200000}, // [213] + /* idx: 214 */ {0x0, 0x0, 0x0, 0x400000}, // [214] + /* idx: 215 */ {0x0, 0x0, 0x0, 0x800000}, // [215] + /* idx: 216 */ {0x0, 0x0, 0x0, 0x1000000}, // [216] + /* idx: 217 */ {0x0, 0x0, 0x0, 0x2000000}, // [217] + /* idx: 218 */ {0x0, 0x0, 0x0, 0x4000000}, // [218] + /* idx: 219 */ {0x0, 0x0, 0x0, 0x8000000}, // [219] + /* idx: 220 */ {0x0, 0x0, 0x0, 0x10000000}, // [220] + /* idx: 221 */ {0x0, 0x0, 0x0, 0x20000000}, // [221] + /* idx: 222 */ {0x0, 0x0, 0x0, 0x40000000}, // [222] + /* idx: 223 */ {0x0, 0x0, 0x0, 0x80000000}, // [223] + /* idx: 224 */ {0x0, 0x0, 0x0, 0x100000000}, // [224] + /* idx: 225 */ {0x0, 0x0, 0x0, 0x200000000}, // [225] + /* idx: 226 */ {0x0, 0x0, 0x0, 0x400000000}, // [226] + /* idx: 227 */ {0x0, 0x0, 0x0, 0x800000000}, // [227] + /* idx: 228 */ {0x0, 0x0, 0x0, 0x1000000000}, // [228] + /* idx: 229 */ {0x0, 0x0, 0x0, 0x2000000000}, // [229] + /* idx: 230 */ {0x0, 0x0, 0x0, 0x4000000000}, // [230] + /* idx: 231 */ {0x0, 0x0, 0x0, 0x8000000000}, // [231] + /* idx: 232 */ {0x0, 0x0, 0x0, 0x10000000000}, // [232] + /* idx: 233 */ {0x0, 0x0, 0x0, 0x20000000000}, // [233] + /* idx: 234 */ {0x0, 0x0, 0x0, 0x40000000000}, // [234] + /* idx: 235 */ {0x0, 0x0, 0x0, 0x80000000000}, // [235] + /* idx: 236 */ {0x0, 0x0, 0x0, 0x100000000000}, // [236] + /* idx: 237 */ {0x0, 0x0, 0x0, 0x200000000000}, // [237] + /* idx: 238 */ {0x0, 0x0, 0x0, 0x400000000000}, // [238] + /* idx: 239 */ {0x0, 0x0, 0x0, 0x800000000000}, // [239] + /* idx: 240 */ {0x0, 0x0, 0x0, 0x1000000000000}, // [240] + /* idx: 241 */ {0x0, 0x0, 0x0, 0x2000000000000}, // [241] + /* idx: 242 */ {0x0, 0x0, 0x0, 0x4000000000000}, // [242] + /* idx: 243 */ {0x0, 0x0, 0x0, 0x8000000000000}, // [243] + /* idx: 244 */ {0x0, 0x0, 0x0, 0x10000000000000}, // [244] + /* idx: 245 */ {0x0, 0x0, 0x0, 0x20000000000000}, // [245] + /* idx: 246 */ {0x0, 0x0, 0x0, 0x40000000000000}, // [246] + /* idx: 247 */ {0x0, 0x0, 0x0, 0x80000000000000}, // [247] + /* idx: 248 */ {0x0, 0x0, 0x0, 0x100000000000000}, // [248] + /* idx: 249 */ {0x0, 0x0, 0x0, 0x200000000000000}, // [249] + /* idx: 250 */ {0x0, 0x0, 0x0, 0x400000000000000}, // [250] + /* idx: 251 */ {0x0, 0x0, 0x0, 0x800000000000000}, // [251] + /* idx: 252 */ {0x0, 0x0, 0x0, 0x1000000000000000}, // [252] + /* idx: 253 */ {0x0, 0x0, 0x0, 0x2000000000000000}, // [253] + /* idx: 254 */ {0x0, 0x0, 0x0, 0x4000000000000000}, // [254] + /* idx: 255 */ {0x0, 0x0, 0x0, 0x8000000000000000}, // [255] +} + +// FringeRoutesLookupTbl, the second 256 Bits, see also the PfxRoutesLookupTbl for the first 256 Bits +// we split 512 bits into 2×256 to leverage BitSet256 optimizations. +// +//nolint:gochecknoglobals // Precomputed read‑only table used in hot paths. +var FringeRoutesLookupTbl = [256]bitset.BitSet256{ + /* idx: 0 */ {0x0, 0x0, 0x0, 0x0}, // invalid + /* idx: 1 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}, // [0, 1, 2, 3, 4, ... ] + /* idx: 2 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0}, // [0, 1, 2, 3, 4, ... ] + /* idx: 3 */ {0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff}, // [128, 129, 130, 131, 132, ... ] + /* idx: 4 */ {0xffffffffffffffff, 0x0, 0x0, 0x0}, // [0, 1, 2, 3, 4, ... ] + /* idx: 5 */ {0x0, 0xffffffffffffffff, 0x0, 0x0}, // [64, 65, 66, 67, 68, ... ] + /* idx: 6 */ {0x0, 0x0, 0xffffffffffffffff, 0x0}, // [128, 129, 130, 131, 132, ... ] + /* idx: 7 */ {0x0, 0x0, 0x0, 0xffffffffffffffff}, // [192, 193, 194, 195, 196, ... ] + /* idx: 8 */ {0xffffffff, 0x0, 0x0, 0x0}, // [0, 1, 2, 3, 4, ... ] + /* idx: 9 */ {0xffffffff00000000, 0x0, 0x0, 0x0}, // [32, 33, 34, 35, 36, ... ] + /* idx: 10 */ {0x0, 0xffffffff, 0x0, 0x0}, // [64, 65, 66, 67, 68, ... ] + /* idx: 11 */ {0x0, 0xffffffff00000000, 0x0, 0x0}, // [96, 97, 98, 99, 100, ... ] + /* idx: 12 */ {0x0, 0x0, 0xffffffff, 0x0}, // [128, 129, 130, 131, 132, ... ] + /* idx: 13 */ {0x0, 0x0, 0xffffffff00000000, 0x0}, // [160, 161, 162, 163, 164, ... ] + /* idx: 14 */ {0x0, 0x0, 0x0, 0xffffffff}, // [192, 193, 194, 195, 196, ... ] + /* idx: 15 */ {0x0, 0x0, 0x0, 0xffffffff00000000}, // [224, 225, 226, 227, 228, ... ] + /* idx: 16 */ {0xffff, 0x0, 0x0, 0x0}, // [0, 1, 2, 3, 4, ... ] + /* idx: 17 */ {0xffff0000, 0x0, 0x0, 0x0}, // [16, 17, 18, 19, 20, ... ] + /* idx: 18 */ {0xffff00000000, 0x0, 0x0, 0x0}, // [32, 33, 34, 35, 36, ... ] + /* idx: 19 */ {0xffff000000000000, 0x0, 0x0, 0x0}, // [48, 49, 50, 51, 52, ... ] + /* idx: 20 */ {0x0, 0xffff, 0x0, 0x0}, // [64, 65, 66, 67, 68, ... ] + /* idx: 21 */ {0x0, 0xffff0000, 0x0, 0x0}, // [80, 81, 82, 83, 84, ... ] + /* idx: 22 */ {0x0, 0xffff00000000, 0x0, 0x0}, // [96, 97, 98, 99, 100, ... ] + /* idx: 23 */ {0x0, 0xffff000000000000, 0x0, 0x0}, // [112, 113, 114, 115, 116, ... ] + /* idx: 24 */ {0x0, 0x0, 0xffff, 0x0}, // [128, 129, 130, 131, 132, ... ] + /* idx: 25 */ {0x0, 0x0, 0xffff0000, 0x0}, // [144, 145, 146, 147, 148, ... ] + /* idx: 26 */ {0x0, 0x0, 0xffff00000000, 0x0}, // [160, 161, 162, 163, 164, ... ] + /* idx: 27 */ {0x0, 0x0, 0xffff000000000000, 0x0}, // [176, 177, 178, 179, 180, ... ] + /* idx: 28 */ {0x0, 0x0, 0x0, 0xffff}, // [192, 193, 194, 195, 196, ... ] + /* idx: 29 */ {0x0, 0x0, 0x0, 0xffff0000}, // [208, 209, 210, 211, 212, ... ] + /* idx: 30 */ {0x0, 0x0, 0x0, 0xffff00000000}, // [224, 225, 226, 227, 228, ... ] + /* idx: 31 */ {0x0, 0x0, 0x0, 0xffff000000000000}, // [240, 241, 242, 243, 244, ... ] + /* idx: 32 */ {0xff, 0x0, 0x0, 0x0}, // [0 1 2 3 4 5 6 7] + /* idx: 33 */ {0xff00, 0x0, 0x0, 0x0}, // [8 9 10 11 12 13 14 15] + /* idx: 34 */ {0xff0000, 0x0, 0x0, 0x0}, // [16 17 18 19 20 21 22 23] + /* idx: 35 */ {0xff000000, 0x0, 0x0, 0x0}, // [24 25 26 27 28 29 30 31] + /* idx: 36 */ {0xff00000000, 0x0, 0x0, 0x0}, // [32 33 34 35 36 37 38 39] + /* idx: 37 */ {0xff0000000000, 0x0, 0x0, 0x0}, // [40 41 42 43 44 45 46 47] + /* idx: 38 */ {0xff000000000000, 0x0, 0x0, 0x0}, // [48 49 50 51 52 53 54 55] + /* idx: 39 */ {0xff00000000000000, 0x0, 0x0, 0x0}, // [56 57 58 59 60 61 62 63] + /* idx: 40 */ {0x0, 0xff, 0x0, 0x0}, // [64 65 66 67 68 69 70 71] + /* idx: 41 */ {0x0, 0xff00, 0x0, 0x0}, // [72 73 74 75 76 77 78 79] + /* idx: 42 */ {0x0, 0xff0000, 0x0, 0x0}, // [80 81 82 83 84 85 86 87] + /* idx: 43 */ {0x0, 0xff000000, 0x0, 0x0}, // [88 89 90 91 92 93 94 95] + /* idx: 44 */ {0x0, 0xff00000000, 0x0, 0x0}, // [96 97 98 99 100 101 102 103] + /* idx: 45 */ {0x0, 0xff0000000000, 0x0, 0x0}, // [104 105 106 107 108 109 110 111] + /* idx: 46 */ {0x0, 0xff000000000000, 0x0, 0x0}, // [112 113 114 115 116 117 118 119] + /* idx: 47 */ {0x0, 0xff00000000000000, 0x0, 0x0}, // [120 121 122 123 124 125 126 127] + /* idx: 48 */ {0x0, 0x0, 0xff, 0x0}, // [128 129 130 131 132 133 134 135] + /* idx: 49 */ {0x0, 0x0, 0xff00, 0x0}, // [136 137 138 139 140 141 142 143] + /* idx: 50 */ {0x0, 0x0, 0xff0000, 0x0}, // [144 145 146 147 148 149 150 151] + /* idx: 51 */ {0x0, 0x0, 0xff000000, 0x0}, // [152 153 154 155 156 157 158 159] + /* idx: 52 */ {0x0, 0x0, 0xff00000000, 0x0}, // [160 161 162 163 164 165 166 167] + /* idx: 53 */ {0x0, 0x0, 0xff0000000000, 0x0}, // [168 169 170 171 172 173 174 175] + /* idx: 54 */ {0x0, 0x0, 0xff000000000000, 0x0}, // [176 177 178 179 180 181 182 183] + /* idx: 55 */ {0x0, 0x0, 0xff00000000000000, 0x0}, // [184 185 186 187 188 189 190 191] + /* idx: 56 */ {0x0, 0x0, 0x0, 0xff}, // [192 193 194 195 196 197 198 199] + /* idx: 57 */ {0x0, 0x0, 0x0, 0xff00}, // [200 201 202 203 204 205 206 207] + /* idx: 58 */ {0x0, 0x0, 0x0, 0xff0000}, // [208 209 210 211 212 213 214 215] + /* idx: 59 */ {0x0, 0x0, 0x0, 0xff000000}, // [216 217 218 219 220 221 222 223] + /* idx: 60 */ {0x0, 0x0, 0x0, 0xff00000000}, // [224 225 226 227 228 229 230 231] + /* idx: 61 */ {0x0, 0x0, 0x0, 0xff0000000000}, // [232 233 234 235 236 237 238 239] + /* idx: 62 */ {0x0, 0x0, 0x0, 0xff000000000000}, // [240 241 242 243 244 245 246 247] + /* idx: 63 */ {0x0, 0x0, 0x0, 0xff00000000000000}, // [248 249 250 251 252 253 254 255] + /* idx: 64 */ {0xf, 0x0, 0x0, 0x0}, // [0 1 2 3] + /* idx: 65 */ {0xf0, 0x0, 0x0, 0x0}, // [4 5 6 7] + /* idx: 66 */ {0xf00, 0x0, 0x0, 0x0}, // [8 9 10 11] + /* idx: 67 */ {0xf000, 0x0, 0x0, 0x0}, // [12 13 14 15] + /* idx: 68 */ {0xf0000, 0x0, 0x0, 0x0}, // [16 17 18 19] + /* idx: 69 */ {0xf00000, 0x0, 0x0, 0x0}, // [20 21 22 23] + /* idx: 70 */ {0xf000000, 0x0, 0x0, 0x0}, // [24 25 26 27] + /* idx: 71 */ {0xf0000000, 0x0, 0x0, 0x0}, // [28 29 30 31] + /* idx: 72 */ {0xf00000000, 0x0, 0x0, 0x0}, // [32 33 34 35] + /* idx: 73 */ {0xf000000000, 0x0, 0x0, 0x0}, // [36 37 38 39] + /* idx: 74 */ {0xf0000000000, 0x0, 0x0, 0x0}, // [40 41 42 43] + /* idx: 75 */ {0xf00000000000, 0x0, 0x0, 0x0}, // [44 45 46 47] + /* idx: 76 */ {0xf000000000000, 0x0, 0x0, 0x0}, // [48 49 50 51] + /* idx: 77 */ {0xf0000000000000, 0x0, 0x0, 0x0}, // [52 53 54 55] + /* idx: 78 */ {0xf00000000000000, 0x0, 0x0, 0x0}, // [56 57 58 59] + /* idx: 79 */ {0xf000000000000000, 0x0, 0x0, 0x0}, // [60 61 62 63] + /* idx: 80 */ {0x0, 0xf, 0x0, 0x0}, // [64 65 66 67] + /* idx: 81 */ {0x0, 0xf0, 0x0, 0x0}, // [68 69 70 71] + /* idx: 82 */ {0x0, 0xf00, 0x0, 0x0}, // [72 73 74 75] + /* idx: 83 */ {0x0, 0xf000, 0x0, 0x0}, // [76 77 78 79] + /* idx: 84 */ {0x0, 0xf0000, 0x0, 0x0}, // [80 81 82 83] + /* idx: 85 */ {0x0, 0xf00000, 0x0, 0x0}, // [84 85 86 87] + /* idx: 86 */ {0x0, 0xf000000, 0x0, 0x0}, // [88 89 90 91] + /* idx: 87 */ {0x0, 0xf0000000, 0x0, 0x0}, // [92 93 94 95] + /* idx: 88 */ {0x0, 0xf00000000, 0x0, 0x0}, // [96 97 98 99] + /* idx: 89 */ {0x0, 0xf000000000, 0x0, 0x0}, // [100 101 102 103] + /* idx: 90 */ {0x0, 0xf0000000000, 0x0, 0x0}, // [104 105 106 107] + /* idx: 91 */ {0x0, 0xf00000000000, 0x0, 0x0}, // [108 109 110 111] + /* idx: 92 */ {0x0, 0xf000000000000, 0x0, 0x0}, // [112 113 114 115] + /* idx: 93 */ {0x0, 0xf0000000000000, 0x0, 0x0}, // [116 117 118 119] + /* idx: 94 */ {0x0, 0xf00000000000000, 0x0, 0x0}, // [120 121 122 123] + /* idx: 95 */ {0x0, 0xf000000000000000, 0x0, 0x0}, // [124 125 126 127] + /* idx: 96 */ {0x0, 0x0, 0xf, 0x0}, // [128 129 130 131] + /* idx: 97 */ {0x0, 0x0, 0xf0, 0x0}, // [132 133 134 135] + /* idx: 98 */ {0x0, 0x0, 0xf00, 0x0}, // [136 137 138 139] + /* idx: 99 */ {0x0, 0x0, 0xf000, 0x0}, // [140 141 142 143] + /* idx: 100 */ {0x0, 0x0, 0xf0000, 0x0}, // [144 145 146 147] + /* idx: 101 */ {0x0, 0x0, 0xf00000, 0x0}, // [148 149 150 151] + /* idx: 102 */ {0x0, 0x0, 0xf000000, 0x0}, // [152 153 154 155] + /* idx: 103 */ {0x0, 0x0, 0xf0000000, 0x0}, // [156 157 158 159] + /* idx: 104 */ {0x0, 0x0, 0xf00000000, 0x0}, // [160 161 162 163] + /* idx: 105 */ {0x0, 0x0, 0xf000000000, 0x0}, // [164 165 166 167] + /* idx: 106 */ {0x0, 0x0, 0xf0000000000, 0x0}, // [168 169 170 171] + /* idx: 107 */ {0x0, 0x0, 0xf00000000000, 0x0}, // [172 173 174 175] + /* idx: 108 */ {0x0, 0x0, 0xf000000000000, 0x0}, // [176 177 178 179] + /* idx: 109 */ {0x0, 0x0, 0xf0000000000000, 0x0}, // [180 181 182 183] + /* idx: 110 */ {0x0, 0x0, 0xf00000000000000, 0x0}, // [184 185 186 187] + /* idx: 111 */ {0x0, 0x0, 0xf000000000000000, 0x0}, // [188 189 190 191] + /* idx: 112 */ {0x0, 0x0, 0x0, 0xf}, // [192 193 194 195] + /* idx: 113 */ {0x0, 0x0, 0x0, 0xf0}, // [196 197 198 199] + /* idx: 114 */ {0x0, 0x0, 0x0, 0xf00}, // [200 201 202 203] + /* idx: 115 */ {0x0, 0x0, 0x0, 0xf000}, // [204 205 206 207] + /* idx: 116 */ {0x0, 0x0, 0x0, 0xf0000}, // [208 209 210 211] + /* idx: 117 */ {0x0, 0x0, 0x0, 0xf00000}, // [212 213 214 215] + /* idx: 118 */ {0x0, 0x0, 0x0, 0xf000000}, // [216 217 218 219] + /* idx: 119 */ {0x0, 0x0, 0x0, 0xf0000000}, // [220 221 222 223] + /* idx: 120 */ {0x0, 0x0, 0x0, 0xf00000000}, // [224 225 226 227] + /* idx: 121 */ {0x0, 0x0, 0x0, 0xf000000000}, // [228 229 230 231] + /* idx: 122 */ {0x0, 0x0, 0x0, 0xf0000000000}, // [232 233 234 235] + /* idx: 123 */ {0x0, 0x0, 0x0, 0xf00000000000}, // [236 237 238 239] + /* idx: 124 */ {0x0, 0x0, 0x0, 0xf000000000000}, // [240 241 242 243] + /* idx: 125 */ {0x0, 0x0, 0x0, 0xf0000000000000}, // [244 245 246 247] + /* idx: 126 */ {0x0, 0x0, 0x0, 0xf00000000000000}, // [248 249 250 251] + /* idx: 127 */ {0x0, 0x0, 0x0, 0xf000000000000000}, // [252 253 254 255] + /* idx: 128 */ {0x3, 0x0, 0x0, 0x0}, // [0 1] + /* idx: 129 */ {0xc, 0x0, 0x0, 0x0}, // [2 3] + /* idx: 130 */ {0x30, 0x0, 0x0, 0x0}, // [4 5] + /* idx: 131 */ {0xc0, 0x0, 0x0, 0x0}, // [6 7] + /* idx: 132 */ {0x300, 0x0, 0x0, 0x0}, // [8 9] + /* idx: 133 */ {0xc00, 0x0, 0x0, 0x0}, // [10 11] + /* idx: 134 */ {0x3000, 0x0, 0x0, 0x0}, // [12 13] + /* idx: 135 */ {0xc000, 0x0, 0x0, 0x0}, // [14 15] + /* idx: 136 */ {0x30000, 0x0, 0x0, 0x0}, // [16 17] + /* idx: 137 */ {0xc0000, 0x0, 0x0, 0x0}, // [18 19] + /* idx: 138 */ {0x300000, 0x0, 0x0, 0x0}, // [20 21] + /* idx: 139 */ {0xc00000, 0x0, 0x0, 0x0}, // [22 23] + /* idx: 140 */ {0x3000000, 0x0, 0x0, 0x0}, // [24 25] + /* idx: 141 */ {0xc000000, 0x0, 0x0, 0x0}, // [26 27] + /* idx: 142 */ {0x30000000, 0x0, 0x0, 0x0}, // [28 29] + /* idx: 143 */ {0xc0000000, 0x0, 0x0, 0x0}, // [30 31] + /* idx: 144 */ {0x300000000, 0x0, 0x0, 0x0}, // [32 33] + /* idx: 145 */ {0xc00000000, 0x0, 0x0, 0x0}, // [34 35] + /* idx: 146 */ {0x3000000000, 0x0, 0x0, 0x0}, // [36 37] + /* idx: 147 */ {0xc000000000, 0x0, 0x0, 0x0}, // [38 39] + /* idx: 148 */ {0x30000000000, 0x0, 0x0, 0x0}, // [40 41] + /* idx: 149 */ {0xc0000000000, 0x0, 0x0, 0x0}, // [42 43] + /* idx: 150 */ {0x300000000000, 0x0, 0x0, 0x0}, // [44 45] + /* idx: 151 */ {0xc00000000000, 0x0, 0x0, 0x0}, // [46 47] + /* idx: 152 */ {0x3000000000000, 0x0, 0x0, 0x0}, // [48 49] + /* idx: 153 */ {0xc000000000000, 0x0, 0x0, 0x0}, // [50 51] + /* idx: 154 */ {0x30000000000000, 0x0, 0x0, 0x0}, // [52 53] + /* idx: 155 */ {0xc0000000000000, 0x0, 0x0, 0x0}, // [54 55] + /* idx: 156 */ {0x300000000000000, 0x0, 0x0, 0x0}, // [56 57] + /* idx: 157 */ {0xc00000000000000, 0x0, 0x0, 0x0}, // [58 59] + /* idx: 158 */ {0x3000000000000000, 0x0, 0x0, 0x0}, // [60 61] + /* idx: 159 */ {0xc000000000000000, 0x0, 0x0, 0x0}, // [62 63] + /* idx: 160 */ {0x0, 0x3, 0x0, 0x0}, // [64 65] + /* idx: 161 */ {0x0, 0xc, 0x0, 0x0}, // [66 67] + /* idx: 162 */ {0x0, 0x30, 0x0, 0x0}, // [68 69] + /* idx: 163 */ {0x0, 0xc0, 0x0, 0x0}, // [70 71] + /* idx: 164 */ {0x0, 0x300, 0x0, 0x0}, // [72 73] + /* idx: 165 */ {0x0, 0xc00, 0x0, 0x0}, // [74 75] + /* idx: 166 */ {0x0, 0x3000, 0x0, 0x0}, // [76 77] + /* idx: 167 */ {0x0, 0xc000, 0x0, 0x0}, // [78 79] + /* idx: 168 */ {0x0, 0x30000, 0x0, 0x0}, // [80 81] + /* idx: 169 */ {0x0, 0xc0000, 0x0, 0x0}, // [82 83] + /* idx: 170 */ {0x0, 0x300000, 0x0, 0x0}, // [84 85] + /* idx: 171 */ {0x0, 0xc00000, 0x0, 0x0}, // [86 87] + /* idx: 172 */ {0x0, 0x3000000, 0x0, 0x0}, // [88 89] + /* idx: 173 */ {0x0, 0xc000000, 0x0, 0x0}, // [90 91] + /* idx: 174 */ {0x0, 0x30000000, 0x0, 0x0}, // [92 93] + /* idx: 175 */ {0x0, 0xc0000000, 0x0, 0x0}, // [94 95] + /* idx: 176 */ {0x0, 0x300000000, 0x0, 0x0}, // [96 97] + /* idx: 177 */ {0x0, 0xc00000000, 0x0, 0x0}, // [98 99] + /* idx: 178 */ {0x0, 0x3000000000, 0x0, 0x0}, // [100 101] + /* idx: 179 */ {0x0, 0xc000000000, 0x0, 0x0}, // [102 103] + /* idx: 180 */ {0x0, 0x30000000000, 0x0, 0x0}, // [104 105] + /* idx: 181 */ {0x0, 0xc0000000000, 0x0, 0x0}, // [106 107] + /* idx: 182 */ {0x0, 0x300000000000, 0x0, 0x0}, // [108 109] + /* idx: 183 */ {0x0, 0xc00000000000, 0x0, 0x0}, // [110 111] + /* idx: 184 */ {0x0, 0x3000000000000, 0x0, 0x0}, // [112 113] + /* idx: 185 */ {0x0, 0xc000000000000, 0x0, 0x0}, // [114 115] + /* idx: 186 */ {0x0, 0x30000000000000, 0x0, 0x0}, // [116 117] + /* idx: 187 */ {0x0, 0xc0000000000000, 0x0, 0x0}, // [118 119] + /* idx: 188 */ {0x0, 0x300000000000000, 0x0, 0x0}, // [120 121] + /* idx: 189 */ {0x0, 0xc00000000000000, 0x0, 0x0}, // [122 123] + /* idx: 190 */ {0x0, 0x3000000000000000, 0x0, 0x0}, // [124 125] + /* idx: 191 */ {0x0, 0xc000000000000000, 0x0, 0x0}, // [126 127] + /* idx: 192 */ {0x0, 0x0, 0x3, 0x0}, // [128 129] + /* idx: 193 */ {0x0, 0x0, 0xc, 0x0}, // [130 131] + /* idx: 194 */ {0x0, 0x0, 0x30, 0x0}, // [132 133] + /* idx: 195 */ {0x0, 0x0, 0xc0, 0x0}, // [134 135] + /* idx: 196 */ {0x0, 0x0, 0x300, 0x0}, // [136 137] + /* idx: 197 */ {0x0, 0x0, 0xc00, 0x0}, // [138 139] + /* idx: 198 */ {0x0, 0x0, 0x3000, 0x0}, // [140 141] + /* idx: 199 */ {0x0, 0x0, 0xc000, 0x0}, // [142 143] + /* idx: 200 */ {0x0, 0x0, 0x30000, 0x0}, // [144 145] + /* idx: 201 */ {0x0, 0x0, 0xc0000, 0x0}, // [146 147] + /* idx: 202 */ {0x0, 0x0, 0x300000, 0x0}, // [148 149] + /* idx: 203 */ {0x0, 0x0, 0xc00000, 0x0}, // [150 151] + /* idx: 204 */ {0x0, 0x0, 0x3000000, 0x0}, // [152 153] + /* idx: 205 */ {0x0, 0x0, 0xc000000, 0x0}, // [154 155] + /* idx: 206 */ {0x0, 0x0, 0x30000000, 0x0}, // [156 157] + /* idx: 207 */ {0x0, 0x0, 0xc0000000, 0x0}, // [158 159] + /* idx: 208 */ {0x0, 0x0, 0x300000000, 0x0}, // [160 161] + /* idx: 209 */ {0x0, 0x0, 0xc00000000, 0x0}, // [162 163] + /* idx: 210 */ {0x0, 0x0, 0x3000000000, 0x0}, // [164 165] + /* idx: 211 */ {0x0, 0x0, 0xc000000000, 0x0}, // [166 167] + /* idx: 212 */ {0x0, 0x0, 0x30000000000, 0x0}, // [168 169] + /* idx: 213 */ {0x0, 0x0, 0xc0000000000, 0x0}, // [170 171] + /* idx: 214 */ {0x0, 0x0, 0x300000000000, 0x0}, // [172 173] + /* idx: 215 */ {0x0, 0x0, 0xc00000000000, 0x0}, // [174 175] + /* idx: 216 */ {0x0, 0x0, 0x3000000000000, 0x0}, // [176 177] + /* idx: 217 */ {0x0, 0x0, 0xc000000000000, 0x0}, // [178 179] + /* idx: 218 */ {0x0, 0x0, 0x30000000000000, 0x0}, // [180 181] + /* idx: 219 */ {0x0, 0x0, 0xc0000000000000, 0x0}, // [182 183] + /* idx: 220 */ {0x0, 0x0, 0x300000000000000, 0x0}, // [184 185] + /* idx: 221 */ {0x0, 0x0, 0xc00000000000000, 0x0}, // [186 187] + /* idx: 222 */ {0x0, 0x0, 0x3000000000000000, 0x0}, // [188 189] + /* idx: 223 */ {0x0, 0x0, 0xc000000000000000, 0x0}, // [190 191] + /* idx: 224 */ {0x0, 0x0, 0x0, 0x3}, // [192 193] + /* idx: 225 */ {0x0, 0x0, 0x0, 0xc}, // [194 195] + /* idx: 226 */ {0x0, 0x0, 0x0, 0x30}, // [196 197] + /* idx: 227 */ {0x0, 0x0, 0x0, 0xc0}, // [198 199] + /* idx: 228 */ {0x0, 0x0, 0x0, 0x300}, // [200 201] + /* idx: 229 */ {0x0, 0x0, 0x0, 0xc00}, // [202 203] + /* idx: 230 */ {0x0, 0x0, 0x0, 0x3000}, // [204 205] + /* idx: 231 */ {0x0, 0x0, 0x0, 0xc000}, // [206 207] + /* idx: 232 */ {0x0, 0x0, 0x0, 0x30000}, // [208 209] + /* idx: 233 */ {0x0, 0x0, 0x0, 0xc0000}, // [210 211] + /* idx: 234 */ {0x0, 0x0, 0x0, 0x300000}, // [212 213] + /* idx: 235 */ {0x0, 0x0, 0x0, 0xc00000}, // [214 215] + /* idx: 236 */ {0x0, 0x0, 0x0, 0x3000000}, // [216 217] + /* idx: 237 */ {0x0, 0x0, 0x0, 0xc000000}, // [218 219] + /* idx: 238 */ {0x0, 0x0, 0x0, 0x30000000}, // [220 221] + /* idx: 239 */ {0x0, 0x0, 0x0, 0xc0000000}, // [222 223] + /* idx: 240 */ {0x0, 0x0, 0x0, 0x300000000}, // [224 225] + /* idx: 241 */ {0x0, 0x0, 0x0, 0xc00000000}, // [226 227] + /* idx: 242 */ {0x0, 0x0, 0x0, 0x3000000000}, // [228 229] + /* idx: 243 */ {0x0, 0x0, 0x0, 0xc000000000}, // [230 231] + /* idx: 244 */ {0x0, 0x0, 0x0, 0x30000000000}, // [232 233] + /* idx: 245 */ {0x0, 0x0, 0x0, 0xc0000000000}, // [234 235] + /* idx: 246 */ {0x0, 0x0, 0x0, 0x300000000000}, // [236 237] + /* idx: 247 */ {0x0, 0x0, 0x0, 0xc00000000000}, // [238 239] + /* idx: 248 */ {0x0, 0x0, 0x0, 0x3000000000000}, // [240 241] + /* idx: 249 */ {0x0, 0x0, 0x0, 0xc000000000000}, // [242 243] + /* idx: 250 */ {0x0, 0x0, 0x0, 0x30000000000000}, // [244 245] + /* idx: 251 */ {0x0, 0x0, 0x0, 0xc0000000000000}, // [246 247] + /* idx: 252 */ {0x0, 0x0, 0x0, 0x300000000000000}, // [248 249] + /* idx: 253 */ {0x0, 0x0, 0x0, 0xc00000000000000}, // [250 251] + /* idx: 254 */ {0x0, 0x0, 0x0, 0x3000000000000000}, // [252 253] + /* idx: 255 */ {0x0, 0x0, 0x0, 0xc000000000000000}, // [254 255] +} diff --git a/vendor/github.com/gaissmai/bart/internal/allot/generate_allottbl.go b/vendor/github.com/gaissmai/bart/internal/allot/generate_allottbl.go new file mode 100644 index 0000000..467e484 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/allot/generate_allottbl.go @@ -0,0 +1,236 @@ +//go:build generate + +//go:generate go run $GOFILE + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +// Package main generates lookup tables for route allocation in the BART routing table. +// +// This generator creates two precomputed lookup tables (PfxRoutesLookupTbl and +// FringeRoutesLookupTbl) that enable fast prefix coverage queries. Each table maps +// a base index (1..255) to a bitset containing all more specific indices covered +// by that prefix. +// +// The tables model a complete binary tree where: +// - Indices 1..255 represent prefixes up to /7 +// - Indices 256..511 represent /8 prefixes (stored separately as "fringe") +package main + +import ( + "fmt" + "os" + "os/exec" + "strings" + "text/template" + + "github.com/gaissmai/bart/internal/bitset" +) + +var ( + thisFname = os.Getenv("GOFILE") + outFname = "allotroutesgenerated.go" +) + +var ( + // prefixAllotTbl holds the bitsets for indices 1..255 (prefixes up to /7). + // For each index idx, the bitset contains all descendant indices in the + // range 1..255 that are covered by the prefix at idx. + prefixAllotTbl [256]bitset.BitSet256 + + // fringeAllotTbl holds the bitsets for indices 1..255, but tracks descendants + // in the range 256..511 (/8 prefixes). The bitset at index idx contains all + // /8 fringe indices (minus 256 offset) covered by the prefix at idx. + fringeAllotTbl [256]bitset.BitSet256 +) + +// data holds the template variables for code generation +var data struct { + File string + PrefixAllotTable string + FringeAllotTable string +} + +// colored prefix for informational and error messages +const ( + INFO = "\x1b[34mINFO:\x1b[0m" + DIE = "\x1b[31mERROR:\x1b[0m" +) + +func main() { + outFile, err := os.Create(outFname) + if err != nil { + fmt.Fprintf(os.Stderr, "%s %v\n", DIE, err) + os.Exit(1) + } + + // Generate both lookup tables using the stack-based algorithm + prefixAllotTbl, fringeAllotTbl = genAllotTables() + + // Populate template data + data.File = thisFname + data.PrefixAllotTable = asString(prefixAllotTbl) + data.FringeAllotTable = asString(fringeAllotTbl) + + // Parse the template ... + t := template.Must(template.New("foo").Parse(codeTemplate)) + + // ... and execute it with our data + err = t.Execute(outFile, data) + if err != nil { + fmt.Fprintf(os.Stderr, "%s %v\n", DIE, err) + _ = outFile.Close() + os.Exit(1) + } + + // Ensure the file is properly closed before formatting + if err := outFile.Close(); err != nil { + fmt.Fprintf(os.Stderr, "%s %v\n", DIE, err) + os.Exit(1) + } + fmt.Fprintf(os.Stdout, "%s ✓ Generated %s\n", INFO, outFname) + + // Run goimports to organize imports and format the code + goimports := exec.Command("goimports", "-w", outFname) + fmt.Fprintf(os.Stdout, "%s Running goimports on %s\n", INFO, outFname) + if out, err := goimports.CombinedOutput(); err != nil { + fmt.Fprintf(os.Stderr, "%s %s\n", DIE, string(out)) + os.Exit(1) + } + fmt.Fprintf(os.Stdout, "%s ✓ goimports completed\n", INFO) + + // Run gofumpt for additional formatting consistency + gofumpt := exec.Command("gofumpt", "-w", outFname) + fmt.Fprintf(os.Stdout, "%s Running gofumpt on %s\n", INFO, outFname) + if out, err := gofumpt.CombinedOutput(); err != nil { + fmt.Fprintf(os.Stderr, "%s %s\n", DIE, string(out)) + os.Exit(1) + } + fmt.Fprintf(os.Stdout, "%s ✓ gofumpt completed\n", INFO) + + fmt.Println() +} + +// genAllotTables generates both prefix and fringe allocation lookup tables. +// +// For each base index idx (1..255), it performs a breadth-first traversal of the +// complete binary tree rooted at idx, collecting all descendant indices. The +// traversal uses a stack-based approach instead of recursion. +// +// The algorithm: +// 1. Start with the root index idx in the stack +// 2. For each index j in the stack: +// - If j < 256: add j to prefixAllotTbl[idx] +// - If j >= 256: add (j-256) to fringeAllotTbl[idx] +// - If j < 256: push children (2*j and 2*j+1) onto the stack +// 3. Continue until the stack is exhausted +// +// This builds a complete binary tree where each node knows all its descendants, +// split into two ranges: [1..255] and [256..511]. +// +// Returns the prefix table (indices 1..255) and fringe table (indices 256..511). +func genAllotTables() (prefix, fringe [256]bitset.BitSet256) { + prefixAllotTbl := [256]bitset.BitSet256{} + fringeAllotTbl := [256]bitset.BitSet256{} + + for idx := 1; idx < 256; idx++ { + // allot algorithm, stack based instead of recursion + stack := make([]int, 0, 512) + stack = append(stack, idx) + + for i := 0; i < len(stack); i++ { + j := stack[i] + if j < 256 { + prefixAllotTbl[idx].Set(uint8(j)) + } else { + fringeAllotTbl[idx].Set(uint8(j - 256)) + } + + // max j is 511, so stop the duplication at 256 and above + if j >= 256 { + continue + } + + // build a complete binary tree + // left: j*2 + // right: (j*2)+1 + stack = append(stack, j<<1, (j<<1)+1) + } + } + return prefixAllotTbl, fringeAllotTbl +} + +// asString converts a lookup table to a formatted Go source string. +// +// Each entry in the table is formatted as: +// +// /* idx: N */ BitSet256{...}, // [list of set bits] +// +// For bitsets with 10 or more set bits, the list is truncated with "..." to +// keep the generated code readable. Index 0 is marked as "invalid" since no +// valid prefix maps to base index 0 in the BART structure. +// +// The returned string is ready to be embedded into the generated Go file. +func asString(tbl [256]bitset.BitSet256) string { + builder := strings.Builder{} + + // Index 0 is invalid (no valid prefix maps to 0) + fmt.Fprintf(&builder, " /* idx: %3d */ %#v, // %s\n", 0, tbl[0], "invalid") + + // Format each valid index with its bitset and the list of set bits, e.g. + // /* idx: 13 */ {0x204a, 0x0, 0x0, 0x0}, // [1 3 6 13] + for idx := 1; idx < 256; idx++ { + fmt.Fprintf(&builder, " /* idx: %3d */ %#v, // ", idx, tbl[idx]) + + bits := tbl[idx].Bits() + if len(bits) < 10 { + fmt.Fprintf(&builder, "%v\n", bits) + } else { + fmt.Fprint(&builder, "[") + for _, bit := range bits[:5] { + fmt.Fprintf(&builder, "%d, ", bit) + } + fmt.Fprintln(&builder, "... ]") + } + } + + return builder.String() +} + +// codeTemplate is the Go source template for the generated allotRoutes_gen.go file. +// It embeds the precomputed lookup tables and includes documentation about +// their structure and usage. +const codeTemplate = `// Code generated by {{.File}}; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package allot + +// PfxRoutesLookupTbl is a lookup table of BitSet256 entries. +// +// It maps a baseIndex (1..255) to a bitset that contains all more +// specific baseIndices that are covered by the prefix at that index. +// +// The idea: +// +// If prefix P has baseIndex idx, then P covers all prefixes in the subtree +// rooted at idx. This table enumerates and encodes those indices. +// +// The table is split: +// - PfxRoutesLookupTbl holds prefixes up to /7 +// - FringeRoutesLookupTbl holds /8 prefixes +// +// This structure allows for very fast set inclusion checks using simple bitwise AND. +// +//nolint:gochecknoglobals // Precomputed read‑only table used in hot paths. +var PfxRoutesLookupTbl = [256]bitset.BitSet256{ +{{.PrefixAllotTable}} } + +// FringeRoutesLookupTbl, the second 256 Bits, see also the PfxRoutesLookupTbl for the first 256 Bits +// we split 512 bits into 2×256 to leverage BitSet256 optimizations. +// +//nolint:gochecknoglobals // Precomputed read‑only table used in hot paths. +var FringeRoutesLookupTbl = [256]bitset.BitSet256{ +{{.FringeAllotTable}} } +` diff --git a/vendor/github.com/gaissmai/bart/internal/art/base_index.go b/vendor/github.com/gaissmai/bart/internal/art/base_index.go new file mode 100644 index 0000000..8323304 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/art/base_index.go @@ -0,0 +1,153 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +// Package art summarizes the functions and inverse functions +// for mapping between a prefix and a baseIndex. +// +// can inline OctetToIdx with cost 6 +// can inline PfxToIdx with cost 10 +// can inline NetMask with cost 13 +// can inline PfxBits with cost 21 +// can inline IdxToPfx with cost 39 +// can inline IdxToRange with cost 71 +package art + +import "math/bits" + +// PfxToIdx maps 8bit prefixes to numbers. The prefixes range from 0/0 to 255/7 +// The return values range from 1 to 255. +// +// [0x0000_00001 .. 0x1111_1111] = [1 .. 255] +// +// example: octet/pfxLen: 160/3 = 0b1010_0000/3 => IdxToPfx(160/3) => 13 +// +// 0b1010_0000 => 0b0000_0101 +// ^^^ >> (8-3) ^^^ +// +// 0b0000_0001 => 0b0000_1000 +// ^ << 3 ^ +// + ----------------------- +// 0b0000_1101 = 13 +// +// ATTENTION: For pfxLen values > 7 the result is undefined! +func PfxToIdx(octet, pfxLen uint8) uint8 { + // use '|' instead of '+', maybe a little bit faster + return octet>>(8-pfxLen) | 1< [128..255] to start +// with the parent (>>1) in the complete binary tree. +// +// Same formula as PfxToIdx, but for octet/8 and a shift (>>1). +// +// octet>>(8-pfxLen) + 1<>(8-8) + 1<<8 +// octet + 256 +// +// got to parent idx: +// (octet+256)>>1 == octet>>1 + 128 +func OctetToIdx(octet uint8) uint8 { + // use '|' instead of '+', maybe a little bit faster + return octet>>1 | 128 +} + +// IdxToPfx returns the octet and prefix len of baseIdx. +// It's the inverse to PfxToIdx. +func IdxToPfx(idx uint8) (octet, pfxLen uint8) { + if idx == 0 { + panic("IdxToPfx: invalid idx 0") + } + // The prefix length corresponds to the number of leading bits in idx. + // bits.Len8 returns the number of bits needed to represent idx as binary, + // so we subtract 1 to recover the prefix length (which is always >= 0). + // Invariant: idx==0 is invalid + + //nolint:gosec //G115: integer overflow conversion int -> uint8 (gosec) + pfxLen = uint8(bits.Len8(idx)) - 1 + + // Compute the number of bits to shift back to obtain the original octet. + shiftBits := 8 - pfxLen + + // Extract the original prefix bits from idx by masking out the low bits. + mask := uint8(0xff) >> shiftBits + + // Shift the masked prefix bits back to their original position. + octet = (idx & mask) << shiftBits + + return octet, pfxLen +} + +// PfxBits returns the bit position of a prefix represented by a base index at a given trie depth. +// +// Each trie level represents an 8-bit stride (one octet). +// The base index contains enough information to recover the prefix length. +// This function returns the full bit offset of the prefix in the address space. +// +// For example: +// +// depth = 2 (i.e. third trie level) +// idx = 13 (which encodes a prefix of length 3 bits within that stride) +// +// => PfxBits = 2*8 + 3 = 19 +func PfxBits(depth int, idx uint8) uint8 { + // bits.Len8(idx) gives the number of significant bits (i.e. prefix length + 1) + // subtract 1 to get the actual prefix length used in this stride + pfxLenInStride := bits.Len8(idx) - 1 + + // Each trie level represents 8 bits (an octet), max depth is 16 + baseBits := depth << 3 // same as depth * 8 + + // Total prefix length in bits, [0..128] + //nolint:gosec // G115: integer overflow conversion int -> uint8 + return uint8(baseBits + pfxLenInStride) +} + +// IdxToRange returns the first and last octets covered by a base index. +// +// The base index encodes a prefix of up to 8 bits inside a single stride (octet). +// This function computes the numerical start and end of the value range for that prefix. +// +// For example: +// +// - A 0-bit prefix (idx == 1) covers the full range: 0..255 +// +// - A 3-bit prefix like 0b101xxxx (idx == 13) covers: 160..191 +// +// idx := PfxToIdx(0b10100000, 3) // 13 +// first, last := IdxToRange(13) // 160, 191 +// +// Internally, this function decodes (octet, prefixLength) via IdxToPfx, +// then computes the broadcast address (last octet) by masking all bits below the prefix length. +func IdxToRange(idx uint8) (first, last uint8) { + // Decode the prefix base (octet) and length (number of fixed bits) + first, pfxLen := IdxToPfx(idx) + + // Compute the "broadcast" value by filling trailing (host) bits with 1s. + // This gives the maximum octet value that still matches the prefix. + last = first | ^NetMask(pfxLen) + + return first, last +} + +// NetMask returns an 8-bit left-aligned network mask for the given number of prefix bits. +// +// For example: +// +// bits = 0 -> 0b00000000 +// bits = 1 -> 0b10000000 +// bits = 2 -> 0b11000000 +// bits = 3 -> 0b11100000 +// ... +// bits = 8 -> 0b11111111 +// +// This mask is used to extract or identify the fixed (prefix) portion of an octet. +// The rightmost (8 - bits) bits are cleared (set to zero), and the upper 'bits' are set to 1. +func NetMask(bits uint8) uint8 { + if bits > 8 { + panic("NetMask: invalid bits > 8") + } + + // Use a full 8-bit mask and shift left to clear trailing (host) bits. + // Shifts 0..8 on a uint8 are well-defined; safe for bits in [0..8]. + return ^uint8(0) << (8 - bits) +} diff --git a/vendor/github.com/gaissmai/bart/internal/bitset/bitset.go b/vendor/github.com/gaissmai/bart/internal/bitset/bitset.go deleted file mode 100644 index 37da871..0000000 --- a/vendor/github.com/gaissmai/bart/internal/bitset/bitset.go +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright (c) 2024 Karl Gaissmaier -// SPDX-License-Identifier: MIT - -// Package bitset implements bitsets, a mapping -// between non-negative integers and boolean values. -// -// Studied [github.com/bits-and-blooms/bitset] inside out -// and rewrote needed parts from scratch for this project. -// -// This implementation is smaller and faster as the more -// general [github.com/bits-and-blooms/bitset]. -// -// All functions can be inlined! -// -// can inline BitSet.Set with cost 63 -// can inline BitSet.Clear with cost 24 -// can inline BitSet.Test with cost 26 -// can inline BitSet.Rank0 with cost 66 -// can inline BitSet.Clone with cost 7 -// can inline BitSet.Compact with cost 35 -// can inline BitSet.FirstSet with cost 25 -// can inline BitSet.NextSet with cost 71 -// can inline BitSet.AsSlice with cost 50 -// can inline BitSet.All with cost 62 -// can inline BitSet.IntersectsAny with cost 42 -// can inline BitSet.IntersectionTop with cost 56 -// can inline BitSet.IntersectionCardinality with cost 35 -// can inline (*BitSet).InPlaceIntersection with cost 71 -// can inline (*BitSet).InPlaceUnion with cost 77 -// can inline BitSet.Size with cost 16 -// can inline popcount with cost 12 -// can inline popcountAnd with cost 30 -package bitset - -import ( - "math/bits" -) - -// A BitSet is a slice of words. This is an internal package -// with a wide open public API. -type BitSet []uint64 - -// xIdx calculates the index of i in a []uint64 -// func wIdx(i uint) int { -// return int(i >> 6) // like (i / 64) but faster -// } - -// bIdx calculates the index of i in a `uint64` -// func bIdx(i uint) uint { -// return i & 63 // like (i % 64) but faster -// } -// -// just as an explanation of the expressions, -// -// i>>6 or i<<6 and i&63 -// -// not factored out as functions to make most of the methods -// inlineable with minimal costs. - -// Set bit i to 1, the capacity of the bitset is increased accordingly. -func (b BitSet) Set(i uint) BitSet { - // grow? - if i >= uint(len(b)<<6) { - words := int((i + 64) >> 6) - switch { - case b == nil: - b = make([]uint64, words) - case cap(b) >= words: - b = b[:words] - default: - // be exact, don't use append! - // max 512 prefixes/node (8*uint64), and a cache line has 64 Bytes - newset := make([]uint64, words) - copy(newset, b) - b = newset - } - } - - b[i>>6] |= 1 << (i & 63) - return b -} - -// Clear bit i to 0. -func (b BitSet) Clear(i uint) BitSet { - if x := int(i >> 6); x < len(b) { - b[x] &^= 1 << (i & 63) - } - return b -} - -// Test if bit i is set. -func (b BitSet) Test(i uint) (ok bool) { - if x := int(i >> 6); x < len(b) { - return b[x]&(1<<(i&63)) != 0 - } - return -} - -// Clone this BitSet, returning a new BitSet that has the same bits set. -func (b BitSet) Clone() BitSet { - return append(b[:0:0], b...) -} - -// Compact, preserve all set bits, while minimizing memory usage. -func (b BitSet) Compact() BitSet { - last := len(b) - 1 - - // find last word with at least one bit set. - for ; last >= 0; last-- { - if b[last] != 0 { - b = b[: last+1 : last+1] - return b - } - } - - // BitSet was empty, shrink to nil - return nil -} - -// FirstSet returns the first bit set along with an ok code. -func (b BitSet) FirstSet() (uint, bool) { - for x, word := range b { - if word != 0 { - return uint(x<<6 + bits.TrailingZeros64(word)), true - } - } - return 0, false -} - -// NextSet returns the next bit set from the specified index, -// including possibly the current index along with an ok code. -func (b BitSet) NextSet(i uint) (uint, bool) { - x := int(i >> 6) - if x >= len(b) { - return 0, false - } - - // process the first (maybe partial) word - first := b[x] >> (i & 63) // i % 64 - if first != 0 { - return i + uint(bits.TrailingZeros64(first)), true - } - - // process the following words until next bit is set - // x < len(b), no out-of-bounds panic in following slice expression - x++ - for j, word := range b[x:] { - if word != 0 { - return uint((x+j)<<6 + bits.TrailingZeros64(word)), true - } - } - return 0, false -} - -// AsSlice returns all set bits as slice of uint without -// heap allocations. -// -// This is faster than All, but also more dangerous, -// it panics if the capacity of buf is < b.Size() -func (b BitSet) AsSlice(buf []uint) []uint { - buf = buf[:cap(buf)] // len = cap - - size := 0 - for idx, word := range b { - for ; word != 0; size++ { - // panics if capacity of buf is exceeded. - buf[size] = uint(idx<<6 + bits.TrailingZeros64(word)) - - // clear the rightmost set bit - word &= word - 1 - } - } - - buf = buf[:size] - return buf -} - -// All returns all set bits. This is simpler but slower than AsSlice. -func (b BitSet) All() []uint { - buf := make([]uint, b.Size()) - - slot := 0 - for idx, word := range b { - for word != 0 { - buf[slot] = uint(idx<<6 + bits.TrailingZeros64(word)) - slot++ - - // clear the rightmost set bit - word &= word - 1 - } - } - - return buf -} - -// IntersectsAny returns true if the intersection of base set with the compare set -// is not the empty set. -func (b BitSet) IntersectsAny(c BitSet) bool { - i := min(len(b), len(c)) - 1 - // bounds check eliminated (BCE) - for ; i >= 0 && i < len(b) && i < len(c); i-- { - if b[i]&c[i] != 0 { - return true - } - } - return false -} - -// IntersectionTop computes the intersection of base set with the compare set. -// If the result set isn't empty, it returns the top most set bit and true. -func (b BitSet) IntersectionTop(c BitSet) (top uint, ok bool) { - i := min(len(b), len(c)) - 1 - // bounds check eliminated (BCE) - for ; i >= 0 && i < len(b) && i < len(c); i-- { - if word := b[i] & c[i]; word != 0 { - return uint(i<<6+bits.Len64(word)) - 1, true - } - } - return -} - -// IntersectionCardinality computes the popcount of the intersection. -func (b BitSet) IntersectionCardinality(c BitSet) int { - return popcntAnd(b, c) -} - -// InPlaceIntersection overwrites and computes the intersection of -// base set with the compare set. This is the BitSet equivalent of & (and). -// If len(c) > len(b), new memory is allocated. -func (b *BitSet) InPlaceIntersection(c BitSet) { - // bounds check eliminated, range until minLen(b,c) - for i := 0; i < len(*b) && i < len(c); i++ { - (*b)[i] &= c[i] - } - - // b >= c - if len(*b) >= len(c) { - // bounds check eliminated - for i := len(c); i < len(*b); i++ { - (*b)[i] = 0 - } - return - } - - // b < c - newset := make([]uint64, len(c)) - copy(newset, *b) - *b = newset -} - -// InPlaceUnion creates the destructive union of base set with compare set. -// This is the BitSet equivalent of | (or). -// If len(c) > len(b), new memory is allocated. -func (b *BitSet) InPlaceUnion(c BitSet) { - // b >= c - if len(*b) >= len(c) { - // bounds check eliminated - for i := 0; i < len(*b) && i < len(c); i++ { - (*b)[i] |= c[i] - } - - return - } - - // b < c - newset := make([]uint64, len(c)) - copy(newset, *b) - *b = newset - - // bounds check eliminated - for i := 0; i < len(*b) && i < len(c); i++ { - (*b)[i] |= c[i] - } -} - -// Size (number of set bits). -func (b BitSet) Size() int { - return popcntSlice(b) -} - -// Rank0 is equal to Rank(i) - 1 -// -// With inlined popcount to make Rank0 itself inlineable. -func (b BitSet) Rank0(i uint) (rnk int) { - // Rank count is inclusive - i++ - - if wordIdx := int(i >> 6); wordIdx >= len(b) { - // inlined popcount, whole slice - for _, x := range b { - rnk += bits.OnesCount64(x) - } - } else { - // inlined popcount, partial slice ... - for _, x := range b[:wordIdx] { - rnk += bits.OnesCount64(x) - } - - // ... plus partial word? - if bitsIdx := i & 63; bitsIdx != 0 { - rnk += bits.OnesCount64(b[wordIdx] << (64 - bitsIdx)) - } - - } - - // correct for offset by one - return rnk - 1 -} - -// popcntSlice -func popcntSlice(s []uint64) (cnt int) { - for _, x := range s { - // count all the bits set in slice. - cnt += bits.OnesCount64(x) - } - return -} - -// popcntAnd -func popcntAnd(s, m []uint64) (cnt int) { - for j := 0; j < len(s) && j < len(m); j++ { - // words are bitwise & followed by popcount. - cnt += bits.OnesCount64(s[j] & m[j]) - } - return -} diff --git a/vendor/github.com/gaissmai/bart/internal/bitset/bitset256.go b/vendor/github.com/gaissmai/bart/internal/bitset/bitset256.go new file mode 100644 index 0000000..5e4f70f --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/bitset/bitset256.go @@ -0,0 +1,595 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +// Package bitset provides a compact and efficient implementation of a fixed-length +// bitset for the range [0..255]. +// +// This implementation is optimized for internal use in a compressed routing trie +// and prioritizes minimal allocation, performance, and inlining. It supports +// constant-time set/test operations, iteration over set bits, ranking, and masked +// intersections. +// +// Internally, the bitset is represented by four uint64 words, providing +// fast bit-level access through direct indexing and hardware-accelerated primitives. +// +// If Go eventually supports SIMD intrinsics, this can be further optimized. +// +// For external consumers, the API intentionally avoids dynamic allocation except +// when explicitly requested (via Bits()). +package bitset + +// can inline (*BitSet256).AsSlice with cost 42 +// can inline (*BitSet256).Bits with cost 47 +// can inline (*BitSet256).Clear with cost 12 +// can inline (*BitSet256).FirstSet with cost 79 +// can inline (*BitSet256).Intersects with cost 48 +// can inline (*BitSet256).Intersection with cost 53 +// can inline (*BitSet256).IntersectionTop with cost 67 +// can inline (*BitSet256).IsEmpty with cost 22 +// can inline (*BitSet256).LastSet with cost 75 +// can inline (*BitSet256).NextSet with cost 65 +// can inline (*BitSet256).Rank with cost 57 +// can inline (*BitSet256).Set with cost 12 +// can inline (*BitSet256).Size with cost 33 +// can inline (*BitSet256).Test with cost 15 +// can inline (*BitSet256).Union with cost 36 + +import ( + "math/bits" +) + +// wordIdx calculates the wordIndex of bit i in a []uint64 +// func wordIdx(i uint) int { +// return int(i >> 6) // like (i / 64) but faster +// } + +// bitIdx calculates the bitIndex of i in an `uint64` +// func bitIdx(i uint) uint { +// return i & 63 // like (i % 64) but mostly faster +// } +// +// just as an explanation of the expressions, +// +// i>>6 or i<<6 and i&63 +// +// not factored out as functions to make most of the methods +// inlineable with minimal costs. + +// BitSet256 represents a fixed-size bitset for the range [0..255], +// stored as four uint64 words (256 bits total). +type BitSet256 [4]uint64 + +// Set sets the bit at position bit (0..255). +func (b *BitSet256) Set(bit uint8) { + b[bit>>6] |= 1 << (bit & 63) +} + +// Clear clears the bit at position bit (0..255). +func (b *BitSet256) Clear(bit uint8) { + b[bit>>6] &^= 1 << (bit & 63) +} + +// Test reports whether the bit at position bit (0..255) is set. +func (b *BitSet256) Test(bit uint8) (ok bool) { + return b[bit>>6]&(1<<(bit&63)) != 0 +} + +// FirstSet returns the index of the lowest (first) bit that is set in the BitSet256. +// +// It searches the 256-bit set in ascending order and returns the position of the +// first bit with value 1. If at least one bit is set, ok is true. +// If no bits are set, ok is false and first is undefined. +// +// Example: +// +// var bs BitSet256 +// bs.Set(17) +// bs.Set(42) +// bs.Set(130) +// bs.Set(255) +// index, ok := bs.FirstSet() // index == 17, ok == true +// +// Note: This implementation avoids a for loop for optimal speed. +// On modern CPUs, computing all four trailing-zero counts up front allows +// the CPU to parallelize these operations internally (pipelining), avoiding +// branch misprediction and maximizing instruction throughput. This technique +// is especially effective for bitsets with known, fixed word count. +func (b *BitSet256) FirstSet() (first uint8, ok bool) { + // optimized for pipelining, can still inline with cost 79 + x0 := bits.TrailingZeros64(b[0]) + x1 := bits.TrailingZeros64(b[1]) + x2 := bits.TrailingZeros64(b[2]) + x3 := bits.TrailingZeros64(b[3]) + + if x0 != 64 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return uint8(x0), true + } + if x1 != 64 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return uint8(x1 + 64), true + } + if x2 != 64 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return uint8(x2 + 128), true + } + if x3 != 64 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return uint8(x3 + 192), true + } + + return +} + +// NextSet returns the index of the next set bit that is greater than or equal to bit. +// +// If such a bit exists, it returns its index as next and ok=true. +// Otherwise, ok is false and next is undefined. +// +// The search starts at the given bit index and proceeds toward higher indices, scanning +// across all four 64-bit segments of the internal bitset representation. +// +// Example: +// +// b.Set(5) +// b.Set(130) +// b.NextSet(0) -> 5, true +// b.NextSet(5) -> 5, true +// b.NextSet(6) -> 130, true +// b.NextSet(200) -> 0, false +func (b *BitSet256) NextSet(bit uint8) (next uint8, ok bool) { + wIdx := int(bit >> 6) + + // process the first (maybe partial) word + first := b[wIdx] >> (bit & 63) + if first != 0 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return bit + uint8(bits.TrailingZeros64(first)), true + } + + // process the following words until next bit is set + for wIdx++; wIdx < 4; wIdx++ { + if next := b[wIdx]; next != 0 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return uint8(wIdx<<6 + bits.TrailingZeros64(next)), true + } + } + return +} + +// LastSet returns the index of the highest (last) bit that is set in the BitSet256. +// +// It searches the bitset in descending order and returns the position of the +// first bit (top bit) with value 1. If at least one bit is set, ok is true. +// If no bits are set, ok is false and last is 0. +// +// Example: +// +// var bs BitSet256 +// bs.Set(2) +// bs.Set(130) +// bs.Set(214) +// index, ok := bs.LastSet() // index == 214, ok == true +func (b *BitSet256) LastSet() (last uint8, ok bool) { + // optimized by unrolling the loop. + // This enables compiler inlining and is ~20% faster. + if b[3] != 0 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return uint8(bits.Len64(b[3]) + 191), true + } + if b[2] != 0 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return uint8(bits.Len64(b[2]) + 127), true + } + if b[1] != 0 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return uint8(bits.Len64(b[1]) + 63), true + } + if b[0] != 0 { + //nolint:gosec // G115: integer overflow conversion int -> uint + return uint8(bits.Len64(b[0]) - 1), true + } + return 0, false +} + +// AsSlice extracts the indices of all set bits in the BitSet256, returning them +// as uint8 values in strictly ascending order. +// +// Performance Considerations: +// To guarantee zero heap allocations and enable compiler inlining, the caller must +// provide a pointer to a 256-byte array (`buf`) as backing storage. The method +// populates this array in-place and returns a sliced view (`[]uint8`) tailored to +// the actual number of set bits. +// +// Safety and Lifecycle: +// The returned slice directly shares the underlying storage of `buf` and is only +// valid until `buf` is modified or reused. This pattern is highly recommended for +// hot paths and performance-critical loops where heap churn must be avoided. +func (b *BitSet256) AsSlice(buf *[256]uint8) []uint8 { + size := 0 + for wIdx, word := range b { + for ; word != 0; size++ { + //nolint:gosec // G115: integer overflow conversion int -> uint + buf[size] = uint8(wIdx<<6 + bits.TrailingZeros64(word)) + word &= word - 1 // clear the rightmost set bit + } + } + + // tailor to the actual number of set bits + return buf[:size] +} + +// Bits returns a slice containing the indices of all set bits in strictly +// ascending order as uint8 values. +// +// Performance Considerations: +// Unlike [AsSlice], this method dynamically allocates a new slice on the +// heap to store the result. It is designed for convenience and APIs where the lifecycle +// of the returned slice needs to outlive the immediate caller's stack frame. +// +// Usage Guidance: +// Use Bits when convenience is preferred over raw performance, or when the result +// must be returned across boundaries where stack-allocated buffers cannot safely escape. +// For high-throughput or allocation-free processing, prefer [AsSlice]. +func (b *BitSet256) Bits() []uint8 { + return b.AsSlice(&[256]uint8{}) +} + +// IntersectionTop computes the intersection of the receiver with c +// and returns the highest (top-most) set bit of the result. +// If the intersection is non-empty, it returns the top bit index and true. +// If the intersection is empty, ok is false and top is 0. +func (b *BitSet256) IntersectionTop(c *BitSet256) (top uint8, ok bool) { + // optimized by unrolling the first word check. + // This enables compiler inlining and is ~15% faster. + if w := b[3] & c[3]; w != 0 { + //nolint:gosec // G115: integer overflow conversion int -> uint8 + return uint8(191 + bits.Len64(w)), true + } + for wIdx := 2; wIdx >= 0; wIdx-- { + if w := b[wIdx] & c[wIdx]; w != 0 { + //nolint:gosec // G115: integer overflow conversion int -> uint8 + return uint8(wIdx<<6 + bits.Len64(w) - 1), true + } + } + return +} + +// Rank returns the number of bits set (i.e., value 1) in the BitSet256 +// up to and including the provided index. +// +// The rank is computed efficiently using precomputed bitmasks (rankMask), +// which mask out all bits above the index. For example: +// +// b.Set(3) +// b.Set(5) +// b.Set(120) +// b.Rank(5) -> 2 // only bits 3 and 5 are ≤ 5 +// b.Rank(119) -> 2 // only bits 3 and 5 are ≤ 119 +// b.Rank(120) -> 3 // bit 120 is included here +// +// Rank is particularly useful in prefix trees, indexing schemes, +// and data compression techniques where ordinal positions matter. +// +// Internally, the function performs four bitwise-and operations +// between the bitset words and a precomputed mask covering bits 0..idx, +// followed by popcount operations (via bits.OnesCount64). +// +// This avoids dynamic mask construction and enables branch-free, highly +// predictable performance. +func (b *BitSet256) Rank(idx uint8) (rnk int) { + rnk += bits.OnesCount64(b[0] & rankMask[idx][0]) + rnk += bits.OnesCount64(b[1] & rankMask[idx][1]) + rnk += bits.OnesCount64(b[2] & rankMask[idx][2]) + rnk += bits.OnesCount64(b[3] & rankMask[idx][3]) + return +} + +// IsEmpty reports whether all 256 bits are zero. +func (b *BitSet256) IsEmpty() bool { + return b[0]|b[1]|b[2]|b[3] == 0 +} + +// Intersects reports whether the receiver and c have at least one bit in common. +func (b *BitSet256) Intersects(c *BitSet256) bool { + return b[0]&c[0] != 0 || + b[1]&c[1] != 0 || + b[2]&c[2] != 0 || + b[3]&c[3] != 0 +} + +// Intersection returns a new BitSet256 containing only the bits +// that are set in both the receiver and c (bitwise AND). +func (b *BitSet256) Intersection(c *BitSet256) (bs BitSet256) { + bs[0] = b[0] & c[0] + bs[1] = b[1] & c[1] + bs[2] = b[2] & c[2] + bs[3] = b[3] & c[3] + return +} + +// Union sets all bits in the receiver that are set in c (in-place bitwise OR). +func (b *BitSet256) Union(c *BitSet256) { + b[0] |= c[0] + b[1] |= c[1] + b[2] |= c[2] + b[3] |= c[3] +} + +// Size returns the population count, i.e. the number of set bits. +func (b *BitSet256) Size() (cnt int) { + cnt += bits.OnesCount64(b[0]) + cnt += bits.OnesCount64(b[1]) + cnt += bits.OnesCount64(b[2]) + cnt += bits.OnesCount64(b[3]) + return +} + +// rankMask is a table of bitmasks with all bits set to 1 up to and including a given bit position. +// It is used by BitSet256.Rank() to perform efficient popcount operations. +// +// This approach trades ~8KB of static memory for zero-allocation, +// fully branch-free, and cache-friendly Rank() calls with constant runtime. +// +// Used internally by the trie for position counting, CIDR ordering, +// and fast range-limited bit population counts. +// +//nolint:gochecknoglobals // Precomputed read‑only table used in hot paths. +var rankMask = [256]BitSet256{ + /* 0 */ {0x1, 0x0, 0x0, 0x0}, + /* 1 */ {0x3, 0x0, 0x0, 0x0}, + /* 2 */ {0x7, 0x0, 0x0, 0x0}, + /* 3 */ {0xf, 0x0, 0x0, 0x0}, + /* 4 */ {0x1f, 0x0, 0x0, 0x0}, + /* 5 */ {0x3f, 0x0, 0x0, 0x0}, + /* 6 */ {0x7f, 0x0, 0x0, 0x0}, + /* 7 */ {0xff, 0x0, 0x0, 0x0}, + /* 8 */ {0x1ff, 0x0, 0x0, 0x0}, + /* 9 */ {0x3ff, 0x0, 0x0, 0x0}, + /* 10 */ {0x7ff, 0x0, 0x0, 0x0}, + /* 11 */ {0xfff, 0x0, 0x0, 0x0}, + /* 12 */ {0x1fff, 0x0, 0x0, 0x0}, + /* 13 */ {0x3fff, 0x0, 0x0, 0x0}, + /* 14 */ {0x7fff, 0x0, 0x0, 0x0}, + /* 15 */ {0xffff, 0x0, 0x0, 0x0}, + /* 16 */ {0x1ffff, 0x0, 0x0, 0x0}, + /* 17 */ {0x3ffff, 0x0, 0x0, 0x0}, + /* 18 */ {0x7ffff, 0x0, 0x0, 0x0}, + /* 19 */ {0xfffff, 0x0, 0x0, 0x0}, + /* 20 */ {0x1fffff, 0x0, 0x0, 0x0}, + /* 21 */ {0x3fffff, 0x0, 0x0, 0x0}, + /* 22 */ {0x7fffff, 0x0, 0x0, 0x0}, + /* 23 */ {0xffffff, 0x0, 0x0, 0x0}, + /* 24 */ {0x1ffffff, 0x0, 0x0, 0x0}, + /* 25 */ {0x3ffffff, 0x0, 0x0, 0x0}, + /* 26 */ {0x7ffffff, 0x0, 0x0, 0x0}, + /* 27 */ {0xfffffff, 0x0, 0x0, 0x0}, + /* 28 */ {0x1fffffff, 0x0, 0x0, 0x0}, + /* 29 */ {0x3fffffff, 0x0, 0x0, 0x0}, + /* 30 */ {0x7fffffff, 0x0, 0x0, 0x0}, + /* 31 */ {0xffffffff, 0x0, 0x0, 0x0}, + /* 32 */ {0x1ffffffff, 0x0, 0x0, 0x0}, + /* 33 */ {0x3ffffffff, 0x0, 0x0, 0x0}, + /* 34 */ {0x7ffffffff, 0x0, 0x0, 0x0}, + /* 35 */ {0xfffffffff, 0x0, 0x0, 0x0}, + /* 36 */ {0x1fffffffff, 0x0, 0x0, 0x0}, + /* 37 */ {0x3fffffffff, 0x0, 0x0, 0x0}, + /* 38 */ {0x7fffffffff, 0x0, 0x0, 0x0}, + /* 39 */ {0xffffffffff, 0x0, 0x0, 0x0}, + /* 40 */ {0x1ffffffffff, 0x0, 0x0, 0x0}, + /* 41 */ {0x3ffffffffff, 0x0, 0x0, 0x0}, + /* 42 */ {0x7ffffffffff, 0x0, 0x0, 0x0}, + /* 43 */ {0xfffffffffff, 0x0, 0x0, 0x0}, + /* 44 */ {0x1fffffffffff, 0x0, 0x0, 0x0}, + /* 45 */ {0x3fffffffffff, 0x0, 0x0, 0x0}, + /* 46 */ {0x7fffffffffff, 0x0, 0x0, 0x0}, + /* 47 */ {0xffffffffffff, 0x0, 0x0, 0x0}, + /* 48 */ {0x1ffffffffffff, 0x0, 0x0, 0x0}, + /* 49 */ {0x3ffffffffffff, 0x0, 0x0, 0x0}, + /* 50 */ {0x7ffffffffffff, 0x0, 0x0, 0x0}, + /* 51 */ {0xfffffffffffff, 0x0, 0x0, 0x0}, + /* 52 */ {0x1fffffffffffff, 0x0, 0x0, 0x0}, + /* 53 */ {0x3fffffffffffff, 0x0, 0x0, 0x0}, + /* 54 */ {0x7fffffffffffff, 0x0, 0x0, 0x0}, + /* 55 */ {0xffffffffffffff, 0x0, 0x0, 0x0}, + /* 56 */ {0x1ffffffffffffff, 0x0, 0x0, 0x0}, + /* 57 */ {0x3ffffffffffffff, 0x0, 0x0, 0x0}, + /* 58 */ {0x7ffffffffffffff, 0x0, 0x0, 0x0}, + /* 59 */ {0xfffffffffffffff, 0x0, 0x0, 0x0}, + /* 60 */ {0x1fffffffffffffff, 0x0, 0x0, 0x0}, + /* 61 */ {0x3fffffffffffffff, 0x0, 0x0, 0x0}, + /* 62 */ {0x7fffffffffffffff, 0x0, 0x0, 0x0}, + /* 63 */ {0xffffffffffffffff, 0x0, 0x0, 0x0}, + /* 64 */ {0xffffffffffffffff, 0x1, 0x0, 0x0}, + /* 65 */ {0xffffffffffffffff, 0x3, 0x0, 0x0}, + /* 66 */ {0xffffffffffffffff, 0x7, 0x0, 0x0}, + /* 67 */ {0xffffffffffffffff, 0xf, 0x0, 0x0}, + /* 68 */ {0xffffffffffffffff, 0x1f, 0x0, 0x0}, + /* 69 */ {0xffffffffffffffff, 0x3f, 0x0, 0x0}, + /* 70 */ {0xffffffffffffffff, 0x7f, 0x0, 0x0}, + /* 71 */ {0xffffffffffffffff, 0xff, 0x0, 0x0}, + /* 72 */ {0xffffffffffffffff, 0x1ff, 0x0, 0x0}, + /* 73 */ {0xffffffffffffffff, 0x3ff, 0x0, 0x0}, + /* 74 */ {0xffffffffffffffff, 0x7ff, 0x0, 0x0}, + /* 75 */ {0xffffffffffffffff, 0xfff, 0x0, 0x0}, + /* 76 */ {0xffffffffffffffff, 0x1fff, 0x0, 0x0}, + /* 77 */ {0xffffffffffffffff, 0x3fff, 0x0, 0x0}, + /* 78 */ {0xffffffffffffffff, 0x7fff, 0x0, 0x0}, + /* 79 */ {0xffffffffffffffff, 0xffff, 0x0, 0x0}, + /* 80 */ {0xffffffffffffffff, 0x1ffff, 0x0, 0x0}, + /* 81 */ {0xffffffffffffffff, 0x3ffff, 0x0, 0x0}, + /* 82 */ {0xffffffffffffffff, 0x7ffff, 0x0, 0x0}, + /* 83 */ {0xffffffffffffffff, 0xfffff, 0x0, 0x0}, + /* 84 */ {0xffffffffffffffff, 0x1fffff, 0x0, 0x0}, + /* 85 */ {0xffffffffffffffff, 0x3fffff, 0x0, 0x0}, + /* 86 */ {0xffffffffffffffff, 0x7fffff, 0x0, 0x0}, + /* 87 */ {0xffffffffffffffff, 0xffffff, 0x0, 0x0}, + /* 88 */ {0xffffffffffffffff, 0x1ffffff, 0x0, 0x0}, + /* 89 */ {0xffffffffffffffff, 0x3ffffff, 0x0, 0x0}, + /* 90 */ {0xffffffffffffffff, 0x7ffffff, 0x0, 0x0}, + /* 91 */ {0xffffffffffffffff, 0xfffffff, 0x0, 0x0}, + /* 92 */ {0xffffffffffffffff, 0x1fffffff, 0x0, 0x0}, + /* 93 */ {0xffffffffffffffff, 0x3fffffff, 0x0, 0x0}, + /* 94 */ {0xffffffffffffffff, 0x7fffffff, 0x0, 0x0}, + /* 95 */ {0xffffffffffffffff, 0xffffffff, 0x0, 0x0}, + /* 96 */ {0xffffffffffffffff, 0x1ffffffff, 0x0, 0x0}, + /* 97 */ {0xffffffffffffffff, 0x3ffffffff, 0x0, 0x0}, + /* 98 */ {0xffffffffffffffff, 0x7ffffffff, 0x0, 0x0}, + /* 99 */ {0xffffffffffffffff, 0xfffffffff, 0x0, 0x0}, + /* 100 */ {0xffffffffffffffff, 0x1fffffffff, 0x0, 0x0}, + /* 101 */ {0xffffffffffffffff, 0x3fffffffff, 0x0, 0x0}, + /* 102 */ {0xffffffffffffffff, 0x7fffffffff, 0x0, 0x0}, + /* 103 */ {0xffffffffffffffff, 0xffffffffff, 0x0, 0x0}, + /* 104 */ {0xffffffffffffffff, 0x1ffffffffff, 0x0, 0x0}, + /* 105 */ {0xffffffffffffffff, 0x3ffffffffff, 0x0, 0x0}, + /* 106 */ {0xffffffffffffffff, 0x7ffffffffff, 0x0, 0x0}, + /* 107 */ {0xffffffffffffffff, 0xfffffffffff, 0x0, 0x0}, + /* 108 */ {0xffffffffffffffff, 0x1fffffffffff, 0x0, 0x0}, + /* 109 */ {0xffffffffffffffff, 0x3fffffffffff, 0x0, 0x0}, + /* 110 */ {0xffffffffffffffff, 0x7fffffffffff, 0x0, 0x0}, + /* 111 */ {0xffffffffffffffff, 0xffffffffffff, 0x0, 0x0}, + /* 112 */ {0xffffffffffffffff, 0x1ffffffffffff, 0x0, 0x0}, + /* 113 */ {0xffffffffffffffff, 0x3ffffffffffff, 0x0, 0x0}, + /* 114 */ {0xffffffffffffffff, 0x7ffffffffffff, 0x0, 0x0}, + /* 115 */ {0xffffffffffffffff, 0xfffffffffffff, 0x0, 0x0}, + /* 116 */ {0xffffffffffffffff, 0x1fffffffffffff, 0x0, 0x0}, + /* 117 */ {0xffffffffffffffff, 0x3fffffffffffff, 0x0, 0x0}, + /* 118 */ {0xffffffffffffffff, 0x7fffffffffffff, 0x0, 0x0}, + /* 119 */ {0xffffffffffffffff, 0xffffffffffffff, 0x0, 0x0}, + /* 120 */ {0xffffffffffffffff, 0x1ffffffffffffff, 0x0, 0x0}, + /* 121 */ {0xffffffffffffffff, 0x3ffffffffffffff, 0x0, 0x0}, + /* 122 */ {0xffffffffffffffff, 0x7ffffffffffffff, 0x0, 0x0}, + /* 123 */ {0xffffffffffffffff, 0xfffffffffffffff, 0x0, 0x0}, + /* 124 */ {0xffffffffffffffff, 0x1fffffffffffffff, 0x0, 0x0}, + /* 125 */ {0xffffffffffffffff, 0x3fffffffffffffff, 0x0, 0x0}, + /* 126 */ {0xffffffffffffffff, 0x7fffffffffffffff, 0x0, 0x0}, + /* 127 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0}, + /* 128 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1, 0x0}, + /* 129 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3, 0x0}, + /* 130 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7, 0x0}, + /* 131 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xf, 0x0}, + /* 132 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1f, 0x0}, + /* 133 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3f, 0x0}, + /* 134 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7f, 0x0}, + /* 135 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xff, 0x0}, + /* 136 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1ff, 0x0}, + /* 137 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3ff, 0x0}, + /* 138 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7ff, 0x0}, + /* 139 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xfff, 0x0}, + /* 140 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1fff, 0x0}, + /* 141 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3fff, 0x0}, + /* 142 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7fff, 0x0}, + /* 143 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffff, 0x0}, + /* 144 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1ffff, 0x0}, + /* 145 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3ffff, 0x0}, + /* 146 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7ffff, 0x0}, + /* 147 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xfffff, 0x0}, + /* 148 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1fffff, 0x0}, + /* 149 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3fffff, 0x0}, + /* 150 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7fffff, 0x0}, + /* 151 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffff, 0x0}, + /* 152 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffff, 0x0}, + /* 153 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffff, 0x0}, + /* 154 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffff, 0x0}, + /* 155 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xfffffff, 0x0}, + /* 156 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffff, 0x0}, + /* 157 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffff, 0x0}, + /* 158 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffff, 0x0}, + /* 159 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff, 0x0}, + /* 160 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffffff, 0x0}, + /* 161 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffffff, 0x0}, + /* 162 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffffff, 0x0}, + /* 163 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffff, 0x0}, + /* 164 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffffff, 0x0}, + /* 165 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffff, 0x0}, + /* 166 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffff, 0x0}, + /* 167 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffff, 0x0}, + /* 168 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffffffff, 0x0}, + /* 169 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffffffff, 0x0}, + /* 170 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffffffff, 0x0}, + /* 171 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffff, 0x0}, + /* 172 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffffffff, 0x0}, + /* 173 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffffff, 0x0}, + /* 174 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffff, 0x0}, + /* 175 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffff, 0x0}, + /* 176 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffffffffff, 0x0}, + /* 177 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffffffffff, 0x0}, + /* 178 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffffffffff, 0x0}, + /* 179 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffff, 0x0}, + /* 180 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffffffffff, 0x0}, + /* 181 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffffffff, 0x0}, + /* 182 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffff, 0x0}, + /* 183 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffff, 0x0}, + /* 184 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffffffffffff, 0x0}, + /* 185 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffffffffffff, 0x0}, + /* 186 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffffffffffff, 0x0}, + /* 187 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffff, 0x0}, + /* 188 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffffffffffff, 0x0}, + /* 189 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffffffffff, 0x0}, + /* 190 */ {0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff, 0x0}, + /* 191 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0}, + /* 192 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1}, + /* 193 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3}, + /* 194 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7}, + /* 195 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xf}, + /* 196 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1f}, + /* 197 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3f}, + /* 198 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7f}, + /* 199 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xff}, + /* 200 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ff}, + /* 201 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3ff}, + /* 202 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7ff}, + /* 203 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfff}, + /* 204 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1fff}, + /* 205 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3fff}, + /* 206 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fff}, + /* 207 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffff}, + /* 208 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ffff}, + /* 209 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3ffff}, + /* 210 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7ffff}, + /* 211 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffff}, + /* 212 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1fffff}, + /* 213 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3fffff}, + /* 214 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffff}, + /* 215 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffff}, + /* 216 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffff}, + /* 217 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffff}, + /* 218 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffff}, + /* 219 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffff}, + /* 220 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffff}, + /* 221 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffff}, + /* 222 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffff}, + /* 223 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffff}, + /* 224 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffffff}, + /* 225 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffffff}, + /* 226 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffffff}, + /* 227 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffff}, + /* 228 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffffff}, + /* 229 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffff}, + /* 230 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffff}, + /* 231 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffff}, + /* 232 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffffffff}, + /* 233 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffffffff}, + /* 234 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffffffff}, + /* 235 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffff}, + /* 236 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffffffff}, + /* 237 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffffff}, + /* 238 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffff}, + /* 239 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffff}, + /* 240 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffffffffff}, + /* 241 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffffffffff}, + /* 242 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffffffffff}, + /* 243 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffff}, + /* 244 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffffffffff}, + /* 245 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffffffff}, + /* 246 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffff}, + /* 247 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffff}, + /* 248 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1ffffffffffffff}, + /* 249 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3ffffffffffffff}, + /* 250 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffffffffffff}, + /* 251 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffff}, + /* 252 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x1fffffffffffffff}, + /* 253 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffffffffff}, + /* 254 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7fffffffffffffff}, + /* 255 */ {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}, +} diff --git a/vendor/github.com/gaissmai/bart/internal/lpm/generate_lookuptbl.go b/vendor/github.com/gaissmai/bart/internal/lpm/generate_lookuptbl.go new file mode 100644 index 0000000..44d34a0 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/lpm/generate_lookuptbl.go @@ -0,0 +1,242 @@ +//go:build generate + +//go:generate go run $GOFILE + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +// Package main generates a lookup table for longest-prefix-match (LPM) operations +// in the BART routing table. +// +// This generator creates a precomputed lookup table (LookupTbl) that enables fast +// prefix matching by replacing iterative backtracking with a single bitset intersection. +// +// The core idea: +// +// In a complete binary tree representation of prefixes, finding the longest matching +// prefix requires checking a node and all its ancestors (parent, grandparent, etc.). +// Instead of iterating through ancestors at runtime (idx >>= 1 in a loop), this table +// precomputes all ancestors for each index. +// +// Binary tree structure: +// - Each index i has a parent at i>>1 (integer division by 2) +// - Index 1 is the root (represents the default route) +// - Indices 2-255 form a 7-level binary tree +// +// Example: Index 13 (binary: 0b1101) has ancestors: +// - 13 itself (0b1101) +// - 6 = 13>>1 (0b0110) - parent +// - 3 = 6>>1 (0b0011) - grandparent +// - 1 = 3>>1 (0b0001) - root +// +// With this table, checking if any ancestor exists in a node's prefix set becomes: +// +// node.prefixes.Intersects(&LookupTbl[idx]) +// +// instead of a loop with multiple Test() calls. +package main + +import ( + "fmt" + "os" + "os/exec" + "strings" + "text/template" + + "github.com/gaissmai/bart/internal/bitset" +) + +var ( + thisFname = os.Getenv("GOFILE") + outFname = "lookuptblgenerated.go" +) + +// data holds the template variables for code generation. +// The LookupTbl field is populated immediately with the generated table string +var data = struct { + File string + LookupTbl string +}{ + File: thisFname, + LookupTbl: genLookupTbl(), +} + +// colored prefix for informational and error messages +const ( + INFO = "\x1b[34mINFO:\x1b[0m" + DIE = "\x1b[31mERROR:\x1b[0m" +) + +func main() { + outFile, err := os.Create(outFname) + if err != nil { + fmt.Fprintf(os.Stderr, "%s %v\n", DIE, err) + os.Exit(1) + } + + // Parse the template ... + t := template.Must(template.New("foo").Parse(codeTemplate)) + + // ... and execute it with our data + err = t.Execute(outFile, data) + if err != nil { + fmt.Fprintf(os.Stderr, "%s %v\n", DIE, err) + _ = outFile.Close() + os.Exit(1) + } + + // Ensure the file is properly closed before formatting + if err := outFile.Close(); err != nil { + fmt.Fprintf(os.Stderr, "%s %v\n", DIE, err) + os.Exit(1) + } + fmt.Fprintf(os.Stdout, "%s ✓ Generated %s\n", INFO, outFname) + + // Run goimports to organize imports and format the code + goimports := exec.Command("goimports", "-w", outFname) + fmt.Fprintf(os.Stdout, "%s Running goimports on %s\n", INFO, outFname) + if out, err := goimports.CombinedOutput(); err != nil { + fmt.Fprintf(os.Stderr, "%s %s\n", DIE, string(out)) + os.Exit(1) + } + fmt.Fprintf(os.Stdout, "%s ✓ goimports completed\n", INFO) + + // Run gofumpt for additional formatting consistency + gofumpt := exec.Command("gofumpt", "-w", outFname) + fmt.Fprintf(os.Stdout, "%s Running gofumpt on %s\n", INFO, outFname) + if out, err := gofumpt.CombinedOutput(); err != nil { + fmt.Fprintf(os.Stderr, "%s %s\n", DIE, string(out)) + os.Exit(1) + } + fmt.Fprintf(os.Stdout, "%s ✓ gofumpt completed\n", INFO) + + fmt.Println() +} + +// genLookupTbl generates the lookup table as a formatted string. +// +// For each index i (1-255), the table stores a bitset containing: +// - i itself +// - all binary ancestors of i (i>>1, i>>2, i>>3, ...) +// +// Example: For index 13 (binary: 1101): +// - Set bit 13 (1101) +// - Set bit 6 (0110) = 13>>1 +// - Set bit 3 (0011) = 6>>1 +// - Set bit 1 (0001) = 3>>1 +// +// This precomputation allows replacing a loop of bitset tests +// with a single bitset intersection operation during longest-prefix-match. + +// genLookupTbl generates the lookup table as a formatted string. +// +// For each index i (1-255), the table stores a BitSet256 containing: +// - i itself (the current node) +// - all binary ancestors of i (obtained by repeatedly right-shifting: i>>1, i>>2, ...) +// +// The algorithm walks up the binary tree from each leaf to the root (index 1). +// Each right-shift operation (i >>= 1) moves from a child to its parent node: +// - Even indices (LSB=0) are left children: parent = i/2 +// - Odd indices (LSB=1) are right children: parent = (i-1)/2 +// - Both cases are handled by integer division via right-shift +// +// Example walkthrough for index 13 (binary: 0b00001101): +// +// Iteration 1: i=13 (0b00001101) => Set bit 13 +// Iteration 2: i=6 (0b00000110) => Set bit 6 (parent of 13) +// Iteration 3: i=3 (0b00000011) => Set bit 3 (parent of 6) +// Iteration 4: i=1 (0b00000001) => Set bit 1 (root) +// Iteration 5: i=0 → Loop terminates +// +// Result: BitSet256 with bits {1, 3, 6, 13} set +// +// This allows longest-prefix-match to be computed with a single bitset intersection: +// +// // Fast O(1) check using precomputed ancestors +// return node.prefixes.Intersects(&LookupTbl[idx]) +// +// instead of iterative backtracking: +// +// // Slow O(log n) loop checking each ancestor individually +// for ; idx > 0; idx >>= 1 { +// if node.prefixes.Test(idx) { +// return true +// } +// } +// +// The generated string is formatted for embedding into Go source code. +func genLookupTbl() string { + // Initialize the lookup table with 256 entries (one per uint8 value) + lookupTbl := [256]bitset.BitSet256{} + + for idx := 1; idx <= 255; idx++ { + // Walk up the binary tree by repeatedly right-shifting + // Each iteration moves to the parent node (idx >> 1) + for i := idx; i > 0; i >>= 1 { + lookupTbl[idx].Set(uint8(i)) + } + } + + // Convert the lookup table to a formatted string for the generated code + builder := strings.Builder{} + + // Index 0 is invalid (no valid prefix maps to 0) + fmt.Fprintf(&builder, " /* idx: %3d */ %#v, // %s\n", 0, lookupTbl[0], "invalid") + + // Format each valid index with its bitset and the list of set bits, e.g. + // /* idx: 13 */ {0x204a, 0x0, 0x0, 0x0}, // [1 3 6 13] + for idx := 1; idx < 256; idx++ { + fmt.Fprintf(&builder, " /* idx: %3d */ %#v, // %v\n", idx, lookupTbl[idx], lookupTbl[idx].Bits()) + } + + return builder.String() +} + +// codeTemplate is the Go source template for the generated lookuptbl_gen.go file. +// It embeds the precomputed lookup table and includes comprehensive documentation +// about its structure, usage, and performance benefits. +// +// The template defines: +// - Package-level documentation explaining the LPM optimization +// - The LookupTbl variable with all 256 precomputed bitsets +// - Usage examples comparing the fast (Intersects) vs slow (loop) approach +// - Warnings about not mutating the read-only table +const codeTemplate = `// Code generated by {{.File}}; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +// Package lpm (longest-prefix-match) contains the lookup table with which +// the backtracking for the lpm in the complete binary tree of the prefixes +// can be replaced by a fast bitset operation. +package lpm + +// LookupTbl is a precomputed read‑only table used in hot paths. +// +// It allows a one-shot bitset intersection algorithm: +// Each entry i encodes i and all its binary ancestors (i>>1, i>>2, ...). +// +// idx must be the uint8 produced by art.OctetToIdx or art.PfxToIdx (0 is invalid). +// +// Usage: +// +// func (n *bartNode[V]) contains(idx uint8) bool { +// return n.prefixes.Intersects(&lpm.LookupTbl[idx]) +// } +// +// instead of a sequence of single bitset tests: +// +// func (n *bartNode[V]) contains(idx uint8) bool { +// for ; idx > 0; idx >>= 1 { +// if n.prefixes.Test(idx) { +// return true +// } +// } +// return false +// } +// +// DO NOT MUTATE: Precomputed read‑only table used in hot paths. +// +//nolint:gochecknoglobals +var LookupTbl = [256]bitset.BitSet256{ +{{.LookupTbl}} }` diff --git a/vendor/github.com/gaissmai/bart/internal/lpm/lookuptblgenerated.go b/vendor/github.com/gaissmai/bart/internal/lpm/lookuptblgenerated.go new file mode 100644 index 0000000..8d89b79 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/lpm/lookuptblgenerated.go @@ -0,0 +1,297 @@ +// Code generated by generate_lookuptbl.go; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +// Package lpm (longest-prefix-match) contains the lookup table with which +// the backtracking for the lpm in the complete binary tree of the prefixes +// can be replaced by a fast bitset operation. +package lpm + +import "github.com/gaissmai/bart/internal/bitset" + +// LookupTbl is a precomputed read‑only table used in hot paths. +// +// It allows a one-shot bitset intersection algorithm: +// Each entry i encodes i and all its binary ancestors (i>>1, i>>2, ...). +// +// idx must be the uint8 produced by art.OctetToIdx or art.PfxToIdx (0 is invalid). +// +// Usage: +// +// func (n *bartNode[V]) contains(idx uint8) bool { +// return n.prefixes.Intersects(&lpm.LookupTbl[idx]) +// } +// +// instead of a sequence of single bitset tests: +// +// func (n *bartNode[V]) contains(idx uint8) bool { +// for ; idx > 0; idx >>= 1 { +// if n.prefixes.Test(idx) { +// return true +// } +// } +// return false +// } +// +// DO NOT MUTATE: Precomputed read‑only table used in hot paths. +// +//nolint:gochecknoglobals +var LookupTbl = [256]bitset.BitSet256{ + /* idx: 0 */ {0x0, 0x0, 0x0, 0x0}, // invalid + /* idx: 1 */ {0x2, 0x0, 0x0, 0x0}, // [1] + /* idx: 2 */ {0x6, 0x0, 0x0, 0x0}, // [1 2] + /* idx: 3 */ {0xa, 0x0, 0x0, 0x0}, // [1 3] + /* idx: 4 */ {0x16, 0x0, 0x0, 0x0}, // [1 2 4] + /* idx: 5 */ {0x26, 0x0, 0x0, 0x0}, // [1 2 5] + /* idx: 6 */ {0x4a, 0x0, 0x0, 0x0}, // [1 3 6] + /* idx: 7 */ {0x8a, 0x0, 0x0, 0x0}, // [1 3 7] + /* idx: 8 */ {0x116, 0x0, 0x0, 0x0}, // [1 2 4 8] + /* idx: 9 */ {0x216, 0x0, 0x0, 0x0}, // [1 2 4 9] + /* idx: 10 */ {0x426, 0x0, 0x0, 0x0}, // [1 2 5 10] + /* idx: 11 */ {0x826, 0x0, 0x0, 0x0}, // [1 2 5 11] + /* idx: 12 */ {0x104a, 0x0, 0x0, 0x0}, // [1 3 6 12] + /* idx: 13 */ {0x204a, 0x0, 0x0, 0x0}, // [1 3 6 13] + /* idx: 14 */ {0x408a, 0x0, 0x0, 0x0}, // [1 3 7 14] + /* idx: 15 */ {0x808a, 0x0, 0x0, 0x0}, // [1 3 7 15] + /* idx: 16 */ {0x10116, 0x0, 0x0, 0x0}, // [1 2 4 8 16] + /* idx: 17 */ {0x20116, 0x0, 0x0, 0x0}, // [1 2 4 8 17] + /* idx: 18 */ {0x40216, 0x0, 0x0, 0x0}, // [1 2 4 9 18] + /* idx: 19 */ {0x80216, 0x0, 0x0, 0x0}, // [1 2 4 9 19] + /* idx: 20 */ {0x100426, 0x0, 0x0, 0x0}, // [1 2 5 10 20] + /* idx: 21 */ {0x200426, 0x0, 0x0, 0x0}, // [1 2 5 10 21] + /* idx: 22 */ {0x400826, 0x0, 0x0, 0x0}, // [1 2 5 11 22] + /* idx: 23 */ {0x800826, 0x0, 0x0, 0x0}, // [1 2 5 11 23] + /* idx: 24 */ {0x100104a, 0x0, 0x0, 0x0}, // [1 3 6 12 24] + /* idx: 25 */ {0x200104a, 0x0, 0x0, 0x0}, // [1 3 6 12 25] + /* idx: 26 */ {0x400204a, 0x0, 0x0, 0x0}, // [1 3 6 13 26] + /* idx: 27 */ {0x800204a, 0x0, 0x0, 0x0}, // [1 3 6 13 27] + /* idx: 28 */ {0x1000408a, 0x0, 0x0, 0x0}, // [1 3 7 14 28] + /* idx: 29 */ {0x2000408a, 0x0, 0x0, 0x0}, // [1 3 7 14 29] + /* idx: 30 */ {0x4000808a, 0x0, 0x0, 0x0}, // [1 3 7 15 30] + /* idx: 31 */ {0x8000808a, 0x0, 0x0, 0x0}, // [1 3 7 15 31] + /* idx: 32 */ {0x100010116, 0x0, 0x0, 0x0}, // [1 2 4 8 16 32] + /* idx: 33 */ {0x200010116, 0x0, 0x0, 0x0}, // [1 2 4 8 16 33] + /* idx: 34 */ {0x400020116, 0x0, 0x0, 0x0}, // [1 2 4 8 17 34] + /* idx: 35 */ {0x800020116, 0x0, 0x0, 0x0}, // [1 2 4 8 17 35] + /* idx: 36 */ {0x1000040216, 0x0, 0x0, 0x0}, // [1 2 4 9 18 36] + /* idx: 37 */ {0x2000040216, 0x0, 0x0, 0x0}, // [1 2 4 9 18 37] + /* idx: 38 */ {0x4000080216, 0x0, 0x0, 0x0}, // [1 2 4 9 19 38] + /* idx: 39 */ {0x8000080216, 0x0, 0x0, 0x0}, // [1 2 4 9 19 39] + /* idx: 40 */ {0x10000100426, 0x0, 0x0, 0x0}, // [1 2 5 10 20 40] + /* idx: 41 */ {0x20000100426, 0x0, 0x0, 0x0}, // [1 2 5 10 20 41] + /* idx: 42 */ {0x40000200426, 0x0, 0x0, 0x0}, // [1 2 5 10 21 42] + /* idx: 43 */ {0x80000200426, 0x0, 0x0, 0x0}, // [1 2 5 10 21 43] + /* idx: 44 */ {0x100000400826, 0x0, 0x0, 0x0}, // [1 2 5 11 22 44] + /* idx: 45 */ {0x200000400826, 0x0, 0x0, 0x0}, // [1 2 5 11 22 45] + /* idx: 46 */ {0x400000800826, 0x0, 0x0, 0x0}, // [1 2 5 11 23 46] + /* idx: 47 */ {0x800000800826, 0x0, 0x0, 0x0}, // [1 2 5 11 23 47] + /* idx: 48 */ {0x100000100104a, 0x0, 0x0, 0x0}, // [1 3 6 12 24 48] + /* idx: 49 */ {0x200000100104a, 0x0, 0x0, 0x0}, // [1 3 6 12 24 49] + /* idx: 50 */ {0x400000200104a, 0x0, 0x0, 0x0}, // [1 3 6 12 25 50] + /* idx: 51 */ {0x800000200104a, 0x0, 0x0, 0x0}, // [1 3 6 12 25 51] + /* idx: 52 */ {0x1000000400204a, 0x0, 0x0, 0x0}, // [1 3 6 13 26 52] + /* idx: 53 */ {0x2000000400204a, 0x0, 0x0, 0x0}, // [1 3 6 13 26 53] + /* idx: 54 */ {0x4000000800204a, 0x0, 0x0, 0x0}, // [1 3 6 13 27 54] + /* idx: 55 */ {0x8000000800204a, 0x0, 0x0, 0x0}, // [1 3 6 13 27 55] + /* idx: 56 */ {0x10000001000408a, 0x0, 0x0, 0x0}, // [1 3 7 14 28 56] + /* idx: 57 */ {0x20000001000408a, 0x0, 0x0, 0x0}, // [1 3 7 14 28 57] + /* idx: 58 */ {0x40000002000408a, 0x0, 0x0, 0x0}, // [1 3 7 14 29 58] + /* idx: 59 */ {0x80000002000408a, 0x0, 0x0, 0x0}, // [1 3 7 14 29 59] + /* idx: 60 */ {0x100000004000808a, 0x0, 0x0, 0x0}, // [1 3 7 15 30 60] + /* idx: 61 */ {0x200000004000808a, 0x0, 0x0, 0x0}, // [1 3 7 15 30 61] + /* idx: 62 */ {0x400000008000808a, 0x0, 0x0, 0x0}, // [1 3 7 15 31 62] + /* idx: 63 */ {0x800000008000808a, 0x0, 0x0, 0x0}, // [1 3 7 15 31 63] + /* idx: 64 */ {0x100010116, 0x1, 0x0, 0x0}, // [1 2 4 8 16 32 64] + /* idx: 65 */ {0x100010116, 0x2, 0x0, 0x0}, // [1 2 4 8 16 32 65] + /* idx: 66 */ {0x200010116, 0x4, 0x0, 0x0}, // [1 2 4 8 16 33 66] + /* idx: 67 */ {0x200010116, 0x8, 0x0, 0x0}, // [1 2 4 8 16 33 67] + /* idx: 68 */ {0x400020116, 0x10, 0x0, 0x0}, // [1 2 4 8 17 34 68] + /* idx: 69 */ {0x400020116, 0x20, 0x0, 0x0}, // [1 2 4 8 17 34 69] + /* idx: 70 */ {0x800020116, 0x40, 0x0, 0x0}, // [1 2 4 8 17 35 70] + /* idx: 71 */ {0x800020116, 0x80, 0x0, 0x0}, // [1 2 4 8 17 35 71] + /* idx: 72 */ {0x1000040216, 0x100, 0x0, 0x0}, // [1 2 4 9 18 36 72] + /* idx: 73 */ {0x1000040216, 0x200, 0x0, 0x0}, // [1 2 4 9 18 36 73] + /* idx: 74 */ {0x2000040216, 0x400, 0x0, 0x0}, // [1 2 4 9 18 37 74] + /* idx: 75 */ {0x2000040216, 0x800, 0x0, 0x0}, // [1 2 4 9 18 37 75] + /* idx: 76 */ {0x4000080216, 0x1000, 0x0, 0x0}, // [1 2 4 9 19 38 76] + /* idx: 77 */ {0x4000080216, 0x2000, 0x0, 0x0}, // [1 2 4 9 19 38 77] + /* idx: 78 */ {0x8000080216, 0x4000, 0x0, 0x0}, // [1 2 4 9 19 39 78] + /* idx: 79 */ {0x8000080216, 0x8000, 0x0, 0x0}, // [1 2 4 9 19 39 79] + /* idx: 80 */ {0x10000100426, 0x10000, 0x0, 0x0}, // [1 2 5 10 20 40 80] + /* idx: 81 */ {0x10000100426, 0x20000, 0x0, 0x0}, // [1 2 5 10 20 40 81] + /* idx: 82 */ {0x20000100426, 0x40000, 0x0, 0x0}, // [1 2 5 10 20 41 82] + /* idx: 83 */ {0x20000100426, 0x80000, 0x0, 0x0}, // [1 2 5 10 20 41 83] + /* idx: 84 */ {0x40000200426, 0x100000, 0x0, 0x0}, // [1 2 5 10 21 42 84] + /* idx: 85 */ {0x40000200426, 0x200000, 0x0, 0x0}, // [1 2 5 10 21 42 85] + /* idx: 86 */ {0x80000200426, 0x400000, 0x0, 0x0}, // [1 2 5 10 21 43 86] + /* idx: 87 */ {0x80000200426, 0x800000, 0x0, 0x0}, // [1 2 5 10 21 43 87] + /* idx: 88 */ {0x100000400826, 0x1000000, 0x0, 0x0}, // [1 2 5 11 22 44 88] + /* idx: 89 */ {0x100000400826, 0x2000000, 0x0, 0x0}, // [1 2 5 11 22 44 89] + /* idx: 90 */ {0x200000400826, 0x4000000, 0x0, 0x0}, // [1 2 5 11 22 45 90] + /* idx: 91 */ {0x200000400826, 0x8000000, 0x0, 0x0}, // [1 2 5 11 22 45 91] + /* idx: 92 */ {0x400000800826, 0x10000000, 0x0, 0x0}, // [1 2 5 11 23 46 92] + /* idx: 93 */ {0x400000800826, 0x20000000, 0x0, 0x0}, // [1 2 5 11 23 46 93] + /* idx: 94 */ {0x800000800826, 0x40000000, 0x0, 0x0}, // [1 2 5 11 23 47 94] + /* idx: 95 */ {0x800000800826, 0x80000000, 0x0, 0x0}, // [1 2 5 11 23 47 95] + /* idx: 96 */ {0x100000100104a, 0x100000000, 0x0, 0x0}, // [1 3 6 12 24 48 96] + /* idx: 97 */ {0x100000100104a, 0x200000000, 0x0, 0x0}, // [1 3 6 12 24 48 97] + /* idx: 98 */ {0x200000100104a, 0x400000000, 0x0, 0x0}, // [1 3 6 12 24 49 98] + /* idx: 99 */ {0x200000100104a, 0x800000000, 0x0, 0x0}, // [1 3 6 12 24 49 99] + /* idx: 100 */ {0x400000200104a, 0x1000000000, 0x0, 0x0}, // [1 3 6 12 25 50 100] + /* idx: 101 */ {0x400000200104a, 0x2000000000, 0x0, 0x0}, // [1 3 6 12 25 50 101] + /* idx: 102 */ {0x800000200104a, 0x4000000000, 0x0, 0x0}, // [1 3 6 12 25 51 102] + /* idx: 103 */ {0x800000200104a, 0x8000000000, 0x0, 0x0}, // [1 3 6 12 25 51 103] + /* idx: 104 */ {0x1000000400204a, 0x10000000000, 0x0, 0x0}, // [1 3 6 13 26 52 104] + /* idx: 105 */ {0x1000000400204a, 0x20000000000, 0x0, 0x0}, // [1 3 6 13 26 52 105] + /* idx: 106 */ {0x2000000400204a, 0x40000000000, 0x0, 0x0}, // [1 3 6 13 26 53 106] + /* idx: 107 */ {0x2000000400204a, 0x80000000000, 0x0, 0x0}, // [1 3 6 13 26 53 107] + /* idx: 108 */ {0x4000000800204a, 0x100000000000, 0x0, 0x0}, // [1 3 6 13 27 54 108] + /* idx: 109 */ {0x4000000800204a, 0x200000000000, 0x0, 0x0}, // [1 3 6 13 27 54 109] + /* idx: 110 */ {0x8000000800204a, 0x400000000000, 0x0, 0x0}, // [1 3 6 13 27 55 110] + /* idx: 111 */ {0x8000000800204a, 0x800000000000, 0x0, 0x0}, // [1 3 6 13 27 55 111] + /* idx: 112 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x0}, // [1 3 7 14 28 56 112] + /* idx: 113 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x0}, // [1 3 7 14 28 56 113] + /* idx: 114 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x0}, // [1 3 7 14 28 57 114] + /* idx: 115 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x0}, // [1 3 7 14 28 57 115] + /* idx: 116 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x0}, // [1 3 7 14 29 58 116] + /* idx: 117 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x0}, // [1 3 7 14 29 58 117] + /* idx: 118 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x0}, // [1 3 7 14 29 59 118] + /* idx: 119 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x0}, // [1 3 7 14 29 59 119] + /* idx: 120 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x0}, // [1 3 7 15 30 60 120] + /* idx: 121 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x0}, // [1 3 7 15 30 60 121] + /* idx: 122 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x0}, // [1 3 7 15 30 61 122] + /* idx: 123 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x0}, // [1 3 7 15 30 61 123] + /* idx: 124 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x0}, // [1 3 7 15 31 62 124] + /* idx: 125 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x0}, // [1 3 7 15 31 62 125] + /* idx: 126 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x0}, // [1 3 7 15 31 63 126] + /* idx: 127 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x0}, // [1 3 7 15 31 63 127] + /* idx: 128 */ {0x100010116, 0x1, 0x1, 0x0}, // [1 2 4 8 16 32 64 128] + /* idx: 129 */ {0x100010116, 0x1, 0x2, 0x0}, // [1 2 4 8 16 32 64 129] + /* idx: 130 */ {0x100010116, 0x2, 0x4, 0x0}, // [1 2 4 8 16 32 65 130] + /* idx: 131 */ {0x100010116, 0x2, 0x8, 0x0}, // [1 2 4 8 16 32 65 131] + /* idx: 132 */ {0x200010116, 0x4, 0x10, 0x0}, // [1 2 4 8 16 33 66 132] + /* idx: 133 */ {0x200010116, 0x4, 0x20, 0x0}, // [1 2 4 8 16 33 66 133] + /* idx: 134 */ {0x200010116, 0x8, 0x40, 0x0}, // [1 2 4 8 16 33 67 134] + /* idx: 135 */ {0x200010116, 0x8, 0x80, 0x0}, // [1 2 4 8 16 33 67 135] + /* idx: 136 */ {0x400020116, 0x10, 0x100, 0x0}, // [1 2 4 8 17 34 68 136] + /* idx: 137 */ {0x400020116, 0x10, 0x200, 0x0}, // [1 2 4 8 17 34 68 137] + /* idx: 138 */ {0x400020116, 0x20, 0x400, 0x0}, // [1 2 4 8 17 34 69 138] + /* idx: 139 */ {0x400020116, 0x20, 0x800, 0x0}, // [1 2 4 8 17 34 69 139] + /* idx: 140 */ {0x800020116, 0x40, 0x1000, 0x0}, // [1 2 4 8 17 35 70 140] + /* idx: 141 */ {0x800020116, 0x40, 0x2000, 0x0}, // [1 2 4 8 17 35 70 141] + /* idx: 142 */ {0x800020116, 0x80, 0x4000, 0x0}, // [1 2 4 8 17 35 71 142] + /* idx: 143 */ {0x800020116, 0x80, 0x8000, 0x0}, // [1 2 4 8 17 35 71 143] + /* idx: 144 */ {0x1000040216, 0x100, 0x10000, 0x0}, // [1 2 4 9 18 36 72 144] + /* idx: 145 */ {0x1000040216, 0x100, 0x20000, 0x0}, // [1 2 4 9 18 36 72 145] + /* idx: 146 */ {0x1000040216, 0x200, 0x40000, 0x0}, // [1 2 4 9 18 36 73 146] + /* idx: 147 */ {0x1000040216, 0x200, 0x80000, 0x0}, // [1 2 4 9 18 36 73 147] + /* idx: 148 */ {0x2000040216, 0x400, 0x100000, 0x0}, // [1 2 4 9 18 37 74 148] + /* idx: 149 */ {0x2000040216, 0x400, 0x200000, 0x0}, // [1 2 4 9 18 37 74 149] + /* idx: 150 */ {0x2000040216, 0x800, 0x400000, 0x0}, // [1 2 4 9 18 37 75 150] + /* idx: 151 */ {0x2000040216, 0x800, 0x800000, 0x0}, // [1 2 4 9 18 37 75 151] + /* idx: 152 */ {0x4000080216, 0x1000, 0x1000000, 0x0}, // [1 2 4 9 19 38 76 152] + /* idx: 153 */ {0x4000080216, 0x1000, 0x2000000, 0x0}, // [1 2 4 9 19 38 76 153] + /* idx: 154 */ {0x4000080216, 0x2000, 0x4000000, 0x0}, // [1 2 4 9 19 38 77 154] + /* idx: 155 */ {0x4000080216, 0x2000, 0x8000000, 0x0}, // [1 2 4 9 19 38 77 155] + /* idx: 156 */ {0x8000080216, 0x4000, 0x10000000, 0x0}, // [1 2 4 9 19 39 78 156] + /* idx: 157 */ {0x8000080216, 0x4000, 0x20000000, 0x0}, // [1 2 4 9 19 39 78 157] + /* idx: 158 */ {0x8000080216, 0x8000, 0x40000000, 0x0}, // [1 2 4 9 19 39 79 158] + /* idx: 159 */ {0x8000080216, 0x8000, 0x80000000, 0x0}, // [1 2 4 9 19 39 79 159] + /* idx: 160 */ {0x10000100426, 0x10000, 0x100000000, 0x0}, // [1 2 5 10 20 40 80 160] + /* idx: 161 */ {0x10000100426, 0x10000, 0x200000000, 0x0}, // [1 2 5 10 20 40 80 161] + /* idx: 162 */ {0x10000100426, 0x20000, 0x400000000, 0x0}, // [1 2 5 10 20 40 81 162] + /* idx: 163 */ {0x10000100426, 0x20000, 0x800000000, 0x0}, // [1 2 5 10 20 40 81 163] + /* idx: 164 */ {0x20000100426, 0x40000, 0x1000000000, 0x0}, // [1 2 5 10 20 41 82 164] + /* idx: 165 */ {0x20000100426, 0x40000, 0x2000000000, 0x0}, // [1 2 5 10 20 41 82 165] + /* idx: 166 */ {0x20000100426, 0x80000, 0x4000000000, 0x0}, // [1 2 5 10 20 41 83 166] + /* idx: 167 */ {0x20000100426, 0x80000, 0x8000000000, 0x0}, // [1 2 5 10 20 41 83 167] + /* idx: 168 */ {0x40000200426, 0x100000, 0x10000000000, 0x0}, // [1 2 5 10 21 42 84 168] + /* idx: 169 */ {0x40000200426, 0x100000, 0x20000000000, 0x0}, // [1 2 5 10 21 42 84 169] + /* idx: 170 */ {0x40000200426, 0x200000, 0x40000000000, 0x0}, // [1 2 5 10 21 42 85 170] + /* idx: 171 */ {0x40000200426, 0x200000, 0x80000000000, 0x0}, // [1 2 5 10 21 42 85 171] + /* idx: 172 */ {0x80000200426, 0x400000, 0x100000000000, 0x0}, // [1 2 5 10 21 43 86 172] + /* idx: 173 */ {0x80000200426, 0x400000, 0x200000000000, 0x0}, // [1 2 5 10 21 43 86 173] + /* idx: 174 */ {0x80000200426, 0x800000, 0x400000000000, 0x0}, // [1 2 5 10 21 43 87 174] + /* idx: 175 */ {0x80000200426, 0x800000, 0x800000000000, 0x0}, // [1 2 5 10 21 43 87 175] + /* idx: 176 */ {0x100000400826, 0x1000000, 0x1000000000000, 0x0}, // [1 2 5 11 22 44 88 176] + /* idx: 177 */ {0x100000400826, 0x1000000, 0x2000000000000, 0x0}, // [1 2 5 11 22 44 88 177] + /* idx: 178 */ {0x100000400826, 0x2000000, 0x4000000000000, 0x0}, // [1 2 5 11 22 44 89 178] + /* idx: 179 */ {0x100000400826, 0x2000000, 0x8000000000000, 0x0}, // [1 2 5 11 22 44 89 179] + /* idx: 180 */ {0x200000400826, 0x4000000, 0x10000000000000, 0x0}, // [1 2 5 11 22 45 90 180] + /* idx: 181 */ {0x200000400826, 0x4000000, 0x20000000000000, 0x0}, // [1 2 5 11 22 45 90 181] + /* idx: 182 */ {0x200000400826, 0x8000000, 0x40000000000000, 0x0}, // [1 2 5 11 22 45 91 182] + /* idx: 183 */ {0x200000400826, 0x8000000, 0x80000000000000, 0x0}, // [1 2 5 11 22 45 91 183] + /* idx: 184 */ {0x400000800826, 0x10000000, 0x100000000000000, 0x0}, // [1 2 5 11 23 46 92 184] + /* idx: 185 */ {0x400000800826, 0x10000000, 0x200000000000000, 0x0}, // [1 2 5 11 23 46 92 185] + /* idx: 186 */ {0x400000800826, 0x20000000, 0x400000000000000, 0x0}, // [1 2 5 11 23 46 93 186] + /* idx: 187 */ {0x400000800826, 0x20000000, 0x800000000000000, 0x0}, // [1 2 5 11 23 46 93 187] + /* idx: 188 */ {0x800000800826, 0x40000000, 0x1000000000000000, 0x0}, // [1 2 5 11 23 47 94 188] + /* idx: 189 */ {0x800000800826, 0x40000000, 0x2000000000000000, 0x0}, // [1 2 5 11 23 47 94 189] + /* idx: 190 */ {0x800000800826, 0x80000000, 0x4000000000000000, 0x0}, // [1 2 5 11 23 47 95 190] + /* idx: 191 */ {0x800000800826, 0x80000000, 0x8000000000000000, 0x0}, // [1 2 5 11 23 47 95 191] + /* idx: 192 */ {0x100000100104a, 0x100000000, 0x0, 0x1}, // [1 3 6 12 24 48 96 192] + /* idx: 193 */ {0x100000100104a, 0x100000000, 0x0, 0x2}, // [1 3 6 12 24 48 96 193] + /* idx: 194 */ {0x100000100104a, 0x200000000, 0x0, 0x4}, // [1 3 6 12 24 48 97 194] + /* idx: 195 */ {0x100000100104a, 0x200000000, 0x0, 0x8}, // [1 3 6 12 24 48 97 195] + /* idx: 196 */ {0x200000100104a, 0x400000000, 0x0, 0x10}, // [1 3 6 12 24 49 98 196] + /* idx: 197 */ {0x200000100104a, 0x400000000, 0x0, 0x20}, // [1 3 6 12 24 49 98 197] + /* idx: 198 */ {0x200000100104a, 0x800000000, 0x0, 0x40}, // [1 3 6 12 24 49 99 198] + /* idx: 199 */ {0x200000100104a, 0x800000000, 0x0, 0x80}, // [1 3 6 12 24 49 99 199] + /* idx: 200 */ {0x400000200104a, 0x1000000000, 0x0, 0x100}, // [1 3 6 12 25 50 100 200] + /* idx: 201 */ {0x400000200104a, 0x1000000000, 0x0, 0x200}, // [1 3 6 12 25 50 100 201] + /* idx: 202 */ {0x400000200104a, 0x2000000000, 0x0, 0x400}, // [1 3 6 12 25 50 101 202] + /* idx: 203 */ {0x400000200104a, 0x2000000000, 0x0, 0x800}, // [1 3 6 12 25 50 101 203] + /* idx: 204 */ {0x800000200104a, 0x4000000000, 0x0, 0x1000}, // [1 3 6 12 25 51 102 204] + /* idx: 205 */ {0x800000200104a, 0x4000000000, 0x0, 0x2000}, // [1 3 6 12 25 51 102 205] + /* idx: 206 */ {0x800000200104a, 0x8000000000, 0x0, 0x4000}, // [1 3 6 12 25 51 103 206] + /* idx: 207 */ {0x800000200104a, 0x8000000000, 0x0, 0x8000}, // [1 3 6 12 25 51 103 207] + /* idx: 208 */ {0x1000000400204a, 0x10000000000, 0x0, 0x10000}, // [1 3 6 13 26 52 104 208] + /* idx: 209 */ {0x1000000400204a, 0x10000000000, 0x0, 0x20000}, // [1 3 6 13 26 52 104 209] + /* idx: 210 */ {0x1000000400204a, 0x20000000000, 0x0, 0x40000}, // [1 3 6 13 26 52 105 210] + /* idx: 211 */ {0x1000000400204a, 0x20000000000, 0x0, 0x80000}, // [1 3 6 13 26 52 105 211] + /* idx: 212 */ {0x2000000400204a, 0x40000000000, 0x0, 0x100000}, // [1 3 6 13 26 53 106 212] + /* idx: 213 */ {0x2000000400204a, 0x40000000000, 0x0, 0x200000}, // [1 3 6 13 26 53 106 213] + /* idx: 214 */ {0x2000000400204a, 0x80000000000, 0x0, 0x400000}, // [1 3 6 13 26 53 107 214] + /* idx: 215 */ {0x2000000400204a, 0x80000000000, 0x0, 0x800000}, // [1 3 6 13 26 53 107 215] + /* idx: 216 */ {0x4000000800204a, 0x100000000000, 0x0, 0x1000000}, // [1 3 6 13 27 54 108 216] + /* idx: 217 */ {0x4000000800204a, 0x100000000000, 0x0, 0x2000000}, // [1 3 6 13 27 54 108 217] + /* idx: 218 */ {0x4000000800204a, 0x200000000000, 0x0, 0x4000000}, // [1 3 6 13 27 54 109 218] + /* idx: 219 */ {0x4000000800204a, 0x200000000000, 0x0, 0x8000000}, // [1 3 6 13 27 54 109 219] + /* idx: 220 */ {0x8000000800204a, 0x400000000000, 0x0, 0x10000000}, // [1 3 6 13 27 55 110 220] + /* idx: 221 */ {0x8000000800204a, 0x400000000000, 0x0, 0x20000000}, // [1 3 6 13 27 55 110 221] + /* idx: 222 */ {0x8000000800204a, 0x800000000000, 0x0, 0x40000000}, // [1 3 6 13 27 55 111 222] + /* idx: 223 */ {0x8000000800204a, 0x800000000000, 0x0, 0x80000000}, // [1 3 6 13 27 55 111 223] + /* idx: 224 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x100000000}, // [1 3 7 14 28 56 112 224] + /* idx: 225 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x200000000}, // [1 3 7 14 28 56 112 225] + /* idx: 226 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x400000000}, // [1 3 7 14 28 56 113 226] + /* idx: 227 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x800000000}, // [1 3 7 14 28 56 113 227] + /* idx: 228 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x1000000000}, // [1 3 7 14 28 57 114 228] + /* idx: 229 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x2000000000}, // [1 3 7 14 28 57 114 229] + /* idx: 230 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x4000000000}, // [1 3 7 14 28 57 115 230] + /* idx: 231 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x8000000000}, // [1 3 7 14 28 57 115 231] + /* idx: 232 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x10000000000}, // [1 3 7 14 29 58 116 232] + /* idx: 233 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x20000000000}, // [1 3 7 14 29 58 116 233] + /* idx: 234 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x40000000000}, // [1 3 7 14 29 58 117 234] + /* idx: 235 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x80000000000}, // [1 3 7 14 29 58 117 235] + /* idx: 236 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x100000000000}, // [1 3 7 14 29 59 118 236] + /* idx: 237 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x200000000000}, // [1 3 7 14 29 59 118 237] + /* idx: 238 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x400000000000}, // [1 3 7 14 29 59 119 238] + /* idx: 239 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x800000000000}, // [1 3 7 14 29 59 119 239] + /* idx: 240 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x1000000000000}, // [1 3 7 15 30 60 120 240] + /* idx: 241 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x2000000000000}, // [1 3 7 15 30 60 120 241] + /* idx: 242 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x4000000000000}, // [1 3 7 15 30 60 121 242] + /* idx: 243 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x8000000000000}, // [1 3 7 15 30 60 121 243] + /* idx: 244 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x10000000000000}, // [1 3 7 15 30 61 122 244] + /* idx: 245 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x20000000000000}, // [1 3 7 15 30 61 122 245] + /* idx: 246 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x40000000000000}, // [1 3 7 15 30 61 123 246] + /* idx: 247 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x80000000000000}, // [1 3 7 15 30 61 123 247] + /* idx: 248 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x100000000000000}, // [1 3 7 15 31 62 124 248] + /* idx: 249 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x200000000000000}, // [1 3 7 15 31 62 124 249] + /* idx: 250 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x400000000000000}, // [1 3 7 15 31 62 125 250] + /* idx: 251 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x800000000000000}, // [1 3 7 15 31 62 125 251] + /* idx: 252 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x1000000000000000}, // [1 3 7 15 31 63 126 252] + /* idx: 253 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x2000000000000000}, // [1 3 7 15 31 63 126 253] + /* idx: 254 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x4000000000000000}, // [1 3 7 15 31 63 127 254] + /* idx: 255 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x8000000000000000}, // [1 3 7 15 31 63 127 255] +} diff --git a/vendor/github.com/gaissmai/bart/internal/nodes/bart.go b/vendor/github.com/gaissmai/bart/internal/nodes/bart.go new file mode 100644 index 0000000..0e2d1e7 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/nodes/bart.go @@ -0,0 +1,265 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package nodes + +import ( + "iter" + + "github.com/gaissmai/bart/internal/lpm" + "github.com/gaissmai/bart/internal/sparse" +) + +// BartNode represents a single trie level in the multibit routing table. +// +// Unlike the original ART algorithm, this implementation uses popcount-compressed +// sparse arrays instead of fixed-size allocations. Insertions and lookups rely on +// fast bitset operations and precomputed lookup tables to maximize CPU pipelining +// and cache efficiency. +// +// Each BartNode maintains two distinct sparse arrays: +// +// 1. Prefixes: Stores routing entries (prefix -> value) for the current stride. +// These are laid out as a complete binary tree using the baseIndex() +// function mapping from the ART algorithm. Prefixes that match exactly at +// the maximum trie depth are always stored here. +// +// 2. Children: Holds pointers to the next logical levels with a branching +// factor of 256 (8 bits per stride). +// +// A slot in the Children array may contain one of three types: +// - *BartNode[V]: An internal intermediate node for further trie traversal. +// - *FringeNode[V]: A path-compressed node if it qualifies as fringe [IsFringe] +// - *LeafNode[V]: A path-compressed node otherwise. +// +// Note: LeafNode and FringeNode are created through path compression and +// are automatically split into regular BartNodes when a more specific prefix +// is inserted that requires further branching. +type BartNode[V any] struct { + Prefixes sparse.Array256[V] + Children sparse.Array256[any] +} + +// IsEmpty returns true if the node contains no routing entries (prefixes) +// and no child nodes. Empty nodes are candidates for compression or removal +// during trie optimization. +func (n *BartNode[V]) IsEmpty() bool { + if n == nil { + return true + } + return n.Prefixes.Len() == 0 && n.Children.Len() == 0 +} + +// PrefixCount returns the number of prefixes stored in this node. +func (n *BartNode[V]) PrefixCount() int { + return n.Prefixes.Len() +} + +// ChildCount returns the number of slots used in this node. +func (n *BartNode[V]) ChildCount() int { + return n.Children.Len() +} + +// InsertPrefix adds or updates a routing entry at the specified index with the given value. +// It returns true if a prefix already existed at that index (indicating an update), +// false if this is a new insertion. +func (n *BartNode[V]) InsertPrefix(idx uint8, val V) (exists bool) { + _, exists = n.Prefixes.InsertAt(idx, val) + return +} + +// GetPrefix retrieves the value associated with the prefix at the given index. +// Returns the value and true if found, or zero value and false if not present. +func (n *BartNode[V]) GetPrefix(idx uint8) (val V, exists bool) { + return n.Prefixes.Get(idx) +} + +// MustGetPrefix retrieves the value at the specified index, panicking if not found. +// This method should only be used when the caller is certain the index exists. +func (n *BartNode[V]) MustGetPrefix(idx uint8) (val V) { + return n.Prefixes.MustGet(idx) +} + +// AllIndices returns an iterator over all prefix entries. +// Each iteration yields the prefix index (uint8) and its associated value (V). +func (n *BartNode[V]) AllIndices() iter.Seq2[uint8, V] { + return func(yield func(uint8, V) bool) { + var buf [256]uint8 + for i, idx := range n.Prefixes.AsSlice(&buf) { + if !yield(idx, n.Prefixes.Items[i]) { + return + } + } + } +} + +// DeletePrefix removes the prefix at the specified index. +// Returns true if the prefix existed, otherwise false. +func (n *BartNode[V]) DeletePrefix(idx uint8) (exists bool) { + _, exists = n.Prefixes.DeleteAt(idx) + return exists +} + +// InsertChild adds a child node at the specified address (0-255). +// The child can be a *BartNode[V], *LeafNode[V], or *FringeNode[V]. +// Returns true if a child already existed at that address. +func (n *BartNode[V]) InsertChild(addr uint8, child any) (exists bool) { + _, exists = n.Children.InsertAt(addr, child) + return +} + +// GetChild retrieves the child node at the specified address. +// Returns the child and true if found, or nil and false if not present. +func (n *BartNode[V]) GetChild(addr uint8) (any, bool) { + return n.Children.Get(addr) +} + +// MustGetChild retrieves the child at the specified address, panicking if not found. +// This method should only be used when the caller is certain the child exists. +func (n *BartNode[V]) MustGetChild(addr uint8) any { + return n.Children.MustGet(addr) +} + +// AllChildren returns an iterator over all child nodes. +// Each iteration yields the child's address (uint8) and the child node (any). +func (n *BartNode[V]) AllChildren() iter.Seq2[uint8, any] { + return func(yield func(addr uint8, child any) bool) { + var buf [256]uint8 + addrs := n.Children.AsSlice(&buf) + for i, addr := range addrs { + if !yield(addr, n.Children.Items[i]) { + return + } + } + } +} + +// DeleteChild removes the child node at the specified address. +// This operation is idempotent - removing a non-existent child is safe. +func (n *BartNode[V]) DeleteChild(addr uint8) (exists bool) { + _, exists = n.Children.DeleteAt(addr) + return exists +} + +// Contains returns true if an index (idx) has any matching longest-prefix +// in the current node’s prefix table. +// +// This function performs a presence check without retrieving the associated value. +// It is faster than a full lookup, as it only tests for intersection with the +// backtracking bitset for the given index. +// +// The prefix table is structured as a complete binary tree (CBT), and LPM testing +// is done via a bitset operation that maps the traversal path from the given index +// toward its possible ancestors. +func (n *BartNode[V]) Contains(idx uint8) bool { + return n.Prefixes.Intersects(&lpm.LookupTbl[idx]) +} + +// LookupIdx performs a longest-prefix match (LPM) lookup for the given index (idx) +// within the 8-bit stride-based prefix table at this trie depth. +// +// The function returns the matched base index, associated value, and true if a +// matching prefix exists at this level; otherwise, ok is false. +// +// Internally, the prefix table is organized as a complete binary tree (CBT) indexed +// via the baseIndex function. Unlike the original ART algorithm, this implementation +// does not use an allotment-based approach. Instead, it performs CBT backtracking +// using a bitset-based operation with a precomputed backtracking pattern specific to idx. +func (n *BartNode[V]) LookupIdx(idx uint8) (top uint8, val V, ok bool) { + // top is the idx of the longest-prefix-match + if top, ok = n.Prefixes.IntersectionTop(&lpm.LookupTbl[idx]); ok { + return top, n.MustGetPrefix(top), true + } + return top, val, ok +} + +// Lookup is just a simple wrapper for LookupIdx. +func (n *BartNode[V]) Lookup(idx uint8) (val V, ok bool) { + _, val, ok = n.LookupIdx(idx) + return val, ok +} + +// CloneFlat returns a shallow copy of the current node, optionally performing deep copies of values. +// +// If cloneFn is nil, the stored values in prefixes are copied directly without modification. +// Otherwise, cloneFn is applied to each stored value for deep cloning. +// Child nodes are cloned shallowly: LeafNode and FringeNode children are cloned via their clone methods, +// but child nodes of type *BartNode[V] (subnodes) are assigned as-is without recursive cloning. +// This method does not recursively clone descendants beyond the immediate children. +// +// Note: The returned node is a new instance with copied slices but only shallow copies of nested nodes, +// except for LeafNode and FringeNode children which are cloned according to cloneFn. +func (n *BartNode[V]) CloneFlat(cloneFn func(V) V) *BartNode[V] { + if n == nil { + return nil + } + + c := new(BartNode[V]) + if n.IsEmpty() { + return c + } + + // copy ... + c.Prefixes = *(n.Prefixes.Copy()) + + // ... and clone the values + if cloneFn != nil { + for i, v := range c.Prefixes.Items { + c.Prefixes.Items[i] = cloneFn(v) + } + } + + // copy ... + c.Children = *(n.Children.Copy()) + + // Iterate over children to flat clone leaf/fringe nodes; + // for *BartNode[V] children, keep shallow references (no recursive clone) + for i, anyKid := range c.Children.Items { + switch kid := anyKid.(type) { + case *BartNode[V]: + // Shallow copy + case *LeafNode[V]: + // Clone leaf nodes, applying cloneFn as needed + c.Children.Items[i] = kid.CloneLeaf(cloneFn) + case *FringeNode[V]: + // Clone fringe nodes, applying cloneFn as needed + c.Children.Items[i] = kid.CloneFringe(cloneFn) + default: + panic("logic error, wrong node type") + } + } + + return c +} + +// CloneRec performs a recursive deep copy of the node and all its descendants. +// +// If cloneFn is nil, the stored values are copied directly without modification. +// Otherwise cloneFn is applied to each stored value for deep cloning. +// +// This method first creates a shallow clone of the current node using CloneFlat, +// applying cloneFn to values as described there. Then it recursively clones all +// child nodes of type *BartNode[V], performing a full deep clone down the subtree. +// +// Child nodes of type *LeafNode[V] and *FringeNode[V] are already cloned +// by CloneFlat. +// +// Returns a new instance of BartNode[V] which is a complete deep clone of the +// receiver node with all descendants. +func (n *BartNode[V]) CloneRec(cloneFn func(V) V) *BartNode[V] { + if n == nil { + return nil + } + + // Perform a flat clone of the current node. + c := n.CloneFlat(cloneFn) + + // Recursively clone all child nodes of type *BartNode[V] + for i, kidAny := range c.Children.Items { + if kid, ok := kidAny.(*BartNode[V]); ok { + c.Children.Items[i] = kid.CloneRec(cloneFn) + } + } + + return c +} diff --git a/vendor/github.com/gaissmai/bart/internal/nodes/bartmethodsgenerated.go b/vendor/github.com/gaissmai/bart/internal/nodes/bartmethodsgenerated.go new file mode 100644 index 0000000..8b92f78 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/nodes/bartmethodsgenerated.go @@ -0,0 +1,2427 @@ +// Code generated from file "commonmethods_tmpl.go"; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package nodes + +import ( + "fmt" + "io" + "net/netip" + "slices" + "strings" + + "github.com/gaissmai/bart/internal/allot" + "github.com/gaissmai/bart/internal/art" + "github.com/gaissmai/bart/internal/value" +) + +// Insert adds or updates a network prefix and its associated value in the trie. +// Traversal begins at the specified byte depth. +// +// The trie utilizes path compression to conserve memory. A prefix is inserted: +// - Uncompressed into a node's prefix table at depth == strideCount. +// - As a path-compressed FringeNode if it qualifies as fringe [IsFringe]. +// - As a path-compressed LeafNode otherwise. +// +// When a new prefix collides with an existing compressed node (Leaf or Fringe), +// Insert resolves the collision by creating a new intermediate node, pushing +// the existing entry down to the next level, and continuing traversal. +// +// Parameters: +// - pfx: The network prefix to insert (must be in canonical/masked form). +// - val: The value to associate with the prefix. +// - depth: The current depth in the trie (0-based byte index). +// +// Returns true if an existing prefix was updated, false if a new insertion occurred. +func (n *BartNode[V]) Insert(pfx netip.Prefix, val V, depth int) (exists bool) { + ip := pfx.Addr() // the pfx must be in canonical form + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the prefix's octets. Each depth corresponds to an 8-bit stride. + // We descend through the trie until we either reach the final stride (depth == strideCount) + // or find an empty child slot where we can path-compress the remaining strides. + for ; depth < len(octets); depth++ { + octet := octets[depth] + + // The current depth matches the prefix's stride count, meaning this is the final + // node for this prefix. We insert it directly into this node's prefix table. + if depth == strideCount { + return n.InsertPrefix(art.PfxToIdx(octet, modBits), val) + } + + // No child exists at this octet path. Instead of creating intermediate nodes + // for the remaining strides, we path-compress the rest of the prefix into a single child slot. + if !n.Children.Test(octet) { + // If the prefix is perfectly aligned with the next stride boundary (e.g., /16 at depth 1), + // it acts as a default route for everything below it. We store it as a FringeNode. + // Otherwise, it has trailing bits or crosses boundaries, so we store it as a LeafNode. + if IsFringe(depth, pfxLen) { + return n.InsertChild(octet, NewFringeNode(val)) + } + return n.InsertChild(octet, NewLeafNode(pfx, val)) + } + + // A child already exists at this octet path. Retrieve it to either continue + // our descent along the strides or resolve a structural collision with a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *BartNode[V]: + // Standard intermediate node: descend to the next trie level. + n = kid + + case *LeafNode[V]: + // Collision with an existing path-compressed LeafNode. + // If it's the exact same prefix, simply update the value. + if kid.Prefix == pfx { + kid.Value = val + return true + } + + // Collision resolution: the paths diverge. + // 1. Create a new intermediate node. + // 2. Push the existing leaf down into this new node. + // 3. Replace the current child slot with the new node. + // 4. Descend into the new node to continue inserting 'pfx'. + newNode := new(BartNode[V]) + newNode.Insert(kid.Prefix, kid.Value, depth+1) + + n.InsertChild(octet, newNode) + n = newNode + + case *FringeNode[V]: + // Collision with an existing path-compressed FringeNode. + // If the incoming prefix is also a fringe at this depth, update the value. + if IsFringe(depth, pfxLen) { + kid.Value = val + return true + } + + // Collision resolution: + // The existing FringeNode acts as a catch-all (default route) for this sub-trie. + // To allow the incoming prefix to branch further, we expand the FringeNode + // into a full intermediate node and place its value at the default route index (1). + newNode := new(BartNode[V]) + newNode.InsertPrefix(1, kid.Value) + + n.InsertChild(octet, newNode) + n = newNode + + default: + panic("logic error, wrong node type") + } + } + panic("unreachable") +} + +// InsertPersist adds or updates a network prefix and its associated value in the trie +// using Copy-On-Write (COW) semantics. Traversal begins at the specified byte depth. +// +// Unlike [Insert], InsertPersist ensures structural integrity of the existing tree +// by cloning internal nodes along the descent path (Copy-On-Write) before mutation. +// +// Parameters: +// - cloneFn: The function used to clone values (V). +// - pfx: The network prefix to insert (must be in canonical/masked form). +// - val: The value to associate with the prefix. +// - depth: The current depth in the trie (0-based byte index). +// +// Returns true if an existing prefix was updated, false if a new insertion occurred. +func (n *BartNode[V]) InsertPersist(cloneFn func(V) V, pfx netip.Prefix, val V, depth int) (exists bool) { + ip := pfx.Addr() // the pfx must be in canonical form + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the prefix's octets. Each depth corresponds to an 8-bit stride. + // We descend through the trie until we either reach the final stride (depth == strideCount) + // or find an empty child slot where we can path-compress the remaining strides. + for ; depth < len(octets); depth++ { + octet := octets[depth] + + // The current depth matches the prefix's stride count, meaning this is the final + // node for this prefix. We insert it directly into this node's prefix table. + if depth == strideCount { + return n.InsertPrefix(art.PfxToIdx(octet, modBits), val) + } + + // No child exists at this octet path. Instead of creating intermediate nodes + // for the remaining strides, we path-compress the rest of the prefix into a single child slot. + if !n.Children.Test(octet) { + // If the prefix is perfectly aligned with the next stride boundary (e.g., /16 at depth 1), + // it acts as a default route for everything below it. We store it as a FringeNode. + // Otherwise, it has trailing bits or crosses boundaries, so we store it as a LeafNode. + if IsFringe(depth, pfxLen) { + return n.InsertChild(octet, NewFringeNode(val)) + } + return n.InsertChild(octet, NewLeafNode(pfx, val)) + } + + // A child already exists at this octet path. Retrieve it to either continue + // our descent along the strides or resolve a structural collision with a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *BartNode[V]: + // Standard intermediate node: Clone the traversed path to maintain persistence (COW). + // We clone the child node before modifying it, then replace the current child slot. + kid = kid.CloneFlat(cloneFn) + n.InsertChild(octet, kid) + n = kid + + case *LeafNode[V]: + // Collision with an existing path-compressed LeafNode. + // If it's the exact same prefix, simply update the value. + if kid.Prefix == pfx { + kid.Value = val + return true + } + + // Collision resolution: the paths diverge. + // 1. Create a new intermediate node. + // 2. Push the existing leaf down into this new node. + // 3. Replace the current child slot with the new node. + // 4. Descend into the new node to continue inserting 'pfx'. + newNode := new(BartNode[V]) + newNode.Insert(kid.Prefix, kid.Value, depth+1) + + n.InsertChild(octet, newNode) + n = newNode + + case *FringeNode[V]: + // Collision with an existing path-compressed FringeNode. + // If the incoming prefix is also a fringe at this depth, update the value. + if IsFringe(depth, pfxLen) { + kid.Value = val + return true + } + + // Collision resolution: + // The existing FringeNode acts as a catch-all (default route) for this sub-trie. + // To allow the incoming prefix to branch further, we expand the FringeNode + // into a full intermediate node and place its value at the default route index (1). + newNode := new(BartNode[V]) + newNode.InsertPrefix(1, kid.Value) + + n.InsertChild(octet, newNode) + n = newNode + + default: + panic("logic error, wrong node type") + } + } + panic("unreachable") +} + +// PurgeAndCompress performs bottom-up trie maintenance to restore path compression +// after a deletion. It unwinds the provided stack of parent nodes, identifying +// nodes that have become sparse (i.e., containing only a single prefix or a single +// child node) and prunes them by promoting the underlying entries to the parent level. +// +// This ensures the trie remains memory-efficient by collapsing redundant intermediate +// nodes back into path-compressed LeafNodes or FringeNodes whenever possible. +// +// Parameters: +// - stack: Array of parent nodes to process during bottom-up unwinding. +// - octets: The full path of octets leading to the current node. +// - is4: True for IPv4 processing, false for IPv6. +func (n *BartNode[V]) PurgeAndCompress(stack []*BartNode[V], octets []uint8, is4 bool) { + // Iterate backwards through the ancestor stack to prune nodes from the bottom up. + for depth := len(stack) - 1; depth >= 0; depth-- { + parent := stack[depth] + octet := octets[depth] + + // Check if the current node is redundant. + // A node may be redundant if it contains exactly one entry (either a prefix or + // a compressed child node). + pfxCount := n.PrefixCount() + childCount := n.ChildCount() + + // If it contains more than one entry, it is always structurally significant and cannot be pruned. + if pfxCount+childCount > 1 { + return + } + + switch { + case childCount == 1: + // The node has exactly one child. We determine if it is a path node, + // a compressed LeafNode, or a compressed FringeNode. + singleAddr, _ := n.Children.FirstSet() + anyKid := n.MustGetChild(singleAddr) + + switch kid := anyKid.(type) { + case *BartNode[V]: + // The child is an intermediate path node; the tree structure is required + // at this level. Compression cannot proceed further up. + return + case *LeafNode[V]: + // The child is a compressed LeafNode. Prune the current node + // and re-insert the leaf into the parent to elevate it. + parent.DeleteChild(octet) + parent.Insert(kid.Prefix, kid.Value, depth) + case *FringeNode[V]: + // The child is a compressed FringeNode. Prune the current node + // and re-insert the fringe as a leaf into the parent. + parent.DeleteChild(octet) + + // Reconstruct the full prefix for the fringe, as path compression + // requires the entire CIDR path, not just the remainder. + // depth is the parent's depth, so we offset by 1 for the kid's position. + fringePfx := CidrForFringe(octets, depth+1, is4, singleAddr) + + parent.Insert(fringePfx, kid.Value, depth) + } + + case pfxCount == 1: + // The node has exactly one prefix. Prune the node and elevate the + // prefix to the parent level as a leaf/fringe. + parent.DeleteChild(octet) + + // Retrieve the single prefix stored in this node. + idx, _ := n.Prefixes.FirstSet() + val := n.MustGetPrefix(idx) + + // Reconstruct the prefix from the path for re-insertion. + path := StridePath{} + copy(path[:], octets) + pfx := CidrFromPath(path, depth+1, is4, idx) + + parent.Insert(pfx, val, depth) + default: + panic("unreachable") + } + + // Move up to the next parent in the stack to continue pruning. + n = parent + } +} + +// Delete removes the prefix from the trie rooted at n and returns true if the +// prefix existed, false if it was not found. The prefix must be in canonical +// (masked) form. +// +// The trie uses path compression, so a prefix may be stored in one of three ways: +// - In the current node's prefix table when the prefix length aligns exactly +// with the stride boundary at this depth (depth == strideCount). +// - As a path-compressed FringeNode in a child slot for stride-aligned prefixes +// (e.g. /8, /16, /24); occurs at depth == strideCount-1. +// - As a path-compressed LeafNode in a child slot for prefixes otherwise. +// +// After a successful deletion, PurgeAndCompress walks the ancestor stack to prune +// now-empty nodes and restore path compression upward. +func (n *BartNode[V]) Delete(pfx netip.Prefix) (exists bool) { + ip := pfx.Addr() // pfx must be in canonical (masked) form + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Record ancestor nodes as we descend; PurgeAndCompress uses this stack to + // walk back up and clean up empty or re-compressible nodes after deletion. + stack := [MaxTreeDepth]*BartNode[V]{} + + for depth, octet := range octets { + depth &= DepthMask // BCE hint; keep Delete on the fast path + + stack[depth] = n // record current node before descending + + // At the stride boundary, the prefix is stored directly in this node's + // prefix table. + if depth == strideCount { + if exists = n.DeletePrefix(art.PfxToIdx(octet, modBits)); !exists { + return false + } + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + } + + // no child node exists at this octet; the prefix is not in the trie + if !n.Children.Test(octet) { + return false + } + + // A child node exists at this octet path, retrieve it. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *BartNode[V]: + n = kid // descend to the next trie level + + case *FringeNode[V]: + // A FringeNode holds a single stride-aligned prefix (/8, /16, ...). + // If pfx does not qualify as a fringe at this depth, it cannot be here. + if !IsFringe(depth, pfxLen) { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + case *LeafNode[V]: + // A LeafNode holds exactly one path-compressed prefix. + // Compare using the canonical (masked) form for an exact match. + if kid.Prefix != pfx { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// DeletePersist removes the prefix from the trie rooted at n using Copy-On-Write (COW) semantics. +// It returns true if the prefix existed, false if it was not found. The prefix must be in +// canonical (masked) form. +// +// Like [Delete], this method uses path compression. However, DeletePersist ensures +// the structural integrity of the existing tree by cloning internal nodes along the +// descent path (COW) before mutation. +// +// After a successful deletion, PurgeAndCompress walks the ancestor stack to prune +// now-empty nodes and restore path compression upward. +func (n *BartNode[V]) DeletePersist(cloneFn func(V) V, pfx netip.Prefix) (exists bool) { + ip := pfx.Addr() // pfx must be in canonical (masked) form + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Record ancestor nodes as we descend; PurgeAndCompress uses this stack to + // walk back up and clean up empty or re-compressible nodes after deletion. + // Since this is a COW operation, we store the cloned nodes here. + stack := [MaxTreeDepth]*BartNode[V]{} + + for depth, octet := range octets { + depth &= DepthMask // BCE hint; keep DeletePersist on the fast path + stack[depth] = n // record current node before descending + + // At the stride boundary, the prefix is stored directly in this node's + // prefix table. + if depth == strideCount { + if exists = n.DeletePrefix(art.PfxToIdx(octet, modBits)); !exists { + return false + } + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + } + + // no child node exists at this octet; the prefix is not in the trie + if !n.Children.Test(octet) { + return false + } + + // A child node exists at this octet path, retrieve it to either continue + // our descent or perform a persistent delete on a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *BartNode[V]: + // Standard intermediate node: Clone the traversed path to maintain + // persistence (COW). We clone the child node before modifying it, + // then replace the current child slot. + kid = kid.CloneFlat(cloneFn) + n.InsertChild(octet, kid) + n = kid + continue + + case *FringeNode[V]: + // A FringeNode holds a single stride-aligned prefix (/8, /16, ...). + // If pfx does not qualify as a fringe at this depth, it cannot be here. + if !IsFringe(depth, pfxLen) { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + case *LeafNode[V]: + // A LeafNode holds exactly one path-compressed prefix. + // Compare using the canonical (masked) form for an exact match. + if kid.Prefix != pfx { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// Get retrieves the value associated with the given network prefix. +// Traversal descends through the trie using the prefix's octets. +// +// The lookup handles path compression transparently: +// - If the path matches an internal node at the target stride, the value is retrieved +// from the node's prefix table. +// - If the path leads to a compressed LeafNode or FringeNode, the function verifies +// the prefix match before returning the value. +// +// Parameters: +// - pfx: The network prefix to look up (must be in canonical form). +// +// Returns: +// - val: The value associated with the prefix (zero value if not found). +// - exists: True if the prefix was found, false otherwise. +func (n *BartNode[V]) Get(pfx netip.Prefix) (val V, exists bool) { + // The prefix must be provided in canonical (masked) form for correct trie traversal. + ip := pfx.Addr() + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the trie octet by octet based on the prefix path. + for depth, octet := range octets { + // At the target stride boundary, the prefix is expected in this node's + // prefix table. + if depth == strideCount { + return n.GetPrefix(art.PfxToIdx(octet, modBits)) + } + + // If no child exists at this path, the prefix is not in the trie. + kidAny, ok := n.GetChild(octet) + if !ok { + return val, false + } + + // Identify the node type at this path segment. + switch kid := kidAny.(type) { + case *BartNode[V]: + // Standard intermediate node: descend to the next level. + n = kid + + case *FringeNode[V]: + // Reached a path-compressed FringeNode. + // Verify if the prefix qualifies as a fringe at this depth to return a match. + if IsFringe(depth, pfxLen) { + return kid.Value, true + } + return val, false + + case *LeafNode[V]: + // Reached a path-compressed LeafNode. + // Check if the stored prefix matches the lookup prefix exactly. + if kid.Prefix == pfx { + return kid.Value, true + } + return val, false + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// Modify performs an in-place modification of a prefix using the provided callback function. +// The callback receives the current value (if found) and existence flag, and returns +// a new value and deletion flag. +// +// Modify returns the size delta (-1, 0, +1). +// This method handles path traversal, node creation for new paths, and automatic +// purge/compress operations after deletions. +// +// Parameters: +// - pfx: The network prefix to modify (must be in canonical form) +// - cb: Callback function that receives (currentValue, exists) and returns (newValue, deleteFlag) +// +// Returns: +// - delta: Size change (-1 for delete, 0 for update/noop, +1 for insert) +func (n *BartNode[V]) Modify(pfx netip.Prefix, cb func(val V, found bool) (_ V, del bool)) (delta int) { + var zero V + + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // record the nodes on the path to the deleted node, needed to purge + // and/or path compress nodes after the deletion of a prefix + stack := [MaxTreeDepth]*BartNode[V]{} + + // find the proper trie node to update prefix + for depth, octet := range octets { + depth &= DepthMask // BCE + + // push current node on stack for path recording + stack[depth] = n + + // The current depth matches the prefix's stride count, meaning this is the final + // stride for this prefix. Insert or update it directly in this node's prefix table. + if depth == strideCount { + idx := art.PfxToIdx(octet, modBits) + + oldVal, existed := n.GetPrefix(idx) + newVal, del := cb(oldVal, existed) + + // update size if necessary + switch { + case !existed && del: // no-op + return 0 + + case existed && del: // delete + n.DeletePrefix(idx) + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return -1 + + case !existed: // insert + n.InsertPrefix(idx, newVal) + return 1 + + case existed: // update + n.InsertPrefix(idx, newVal) + return 0 + + default: + panic("unreachable") + } + + } + + // go down in tight loop to last octet + if !n.Children.Test(octet) { + // insert prefix path compressed + + newVal, del := cb(zero, false) + if del { + return 0 + } + + // insert + if IsFringe(depth, pfxLen) { + n.InsertChild(octet, NewFringeNode(newVal)) + } else { + n.InsertChild(octet, NewLeafNode(pfx, newVal)) + } + + return 1 + } + + // n.children.Test(octet) == true + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *BartNode[V]: + n = kid // descend down to next trie level + continue + + case *LeafNode[V]: + oldVal := kid.Value + + // update existing value if prefixes are equal + if kid.Prefix == pfx { + newVal, del := cb(oldVal, true) + + if !del { + kid.Value = newVal + return 0 + } + + // delete + n.DeleteChild(octet) + + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + + return -1 + } + + // stop if this is a no-op for zero values + newVal, del := cb(zero, false) + if del { + return 0 + } + + // create new node + // insert new child at current leaf position (octet) + newNode := new(BartNode[V]) + n.InsertChild(octet, newNode) + + // push the leaf down + // insert pfx with newVal in new node + newNode.Insert(kid.Prefix, kid.Value, depth+1) + newNode.Insert(pfx, newVal, depth+1) + + return 1 + + case *FringeNode[V]: + // update existing value if prefix is fringe + if IsFringe(depth, pfxLen) { + newVal, del := cb(kid.Value, true) + if !del { + kid.Value = newVal + return 0 + } + + // delete + n.DeleteChild(octet) + + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + + return -1 + } + + // stop if this is a no-op for zero values + newVal, del := cb(zero, false) + if del { + return 0 + } + + // create new node + // insert new child at current leaf position (octet) + newNode := new(BartNode[V]) + n.InsertChild(octet, newNode) + + // push the fringe down, it becomes a default route (idx=1) + // insert pfx with newVal in new node + newNode.InsertPrefix(1, kid.Value) + newNode.Insert(pfx, newVal, depth+1) + + return 1 + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// EqualRec performs recursive structural equality comparison between two nodes. +// Compares prefix and child bitsets, then recursively compares all stored values +// and child nodes. Returns true if the nodes and their entire subtrees are +// structurally and semantically identical, false otherwise. +// +// The comparison handles different node types (internal nodes, leafNodes, fringeNodes) +// and uses the equal function for value comparisons to support custom equality logic. +func (n *BartNode[V]) EqualRec(o *BartNode[V]) bool { + if n == nil || o == nil { + return n == o + } + if n == o { + return true + } + + if n.Prefixes.BitSet256 != o.Prefixes.BitSet256 { + return false + } + + if n.Children.BitSet256 != o.Children.BitSet256 { + return false + } + + for idx, nVal := range n.AllIndices() { + oVal := o.MustGetPrefix(idx) // mustGet is ok, bitsets are equal + if !value.Equal(nVal, oVal) { + return false + } + } + + for addr, nKid := range n.AllChildren() { + oKid := o.MustGetChild(addr) // mustGet is ok, bitsets are equal + + switch nKid := nKid.(type) { + case *BartNode[V]: + // oKid must also be a node + oKid, ok := oKid.(*BartNode[V]) + if !ok { + return false + } + + // compare rec-descent + if !nKid.EqualRec(oKid) { + return false + } + + case *LeafNode[V]: + // oKid must also be a leaf + oKid, ok := oKid.(*LeafNode[V]) + if !ok { + return false + } + + // compare prefixes + if nKid.Prefix != oKid.Prefix { + return false + } + + // compare values + if !value.Equal(nKid.Value, oKid.Value) { + return false + } + + case *FringeNode[V]: + // oKid must also be a fringe + oKid, ok := oKid.(*FringeNode[V]) + if !ok { + return false + } + + // compare values + if !value.Equal(nKid.Value, oKid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// DumpRec recursively descends the trie rooted at n and writes a human-readable +// representation of each visited node to w. +// +// It returns immediately if n is nil or empty. For each visited internal node +// it calls dump to write the node's representation, then iterates its child +// addresses and recurses into children of type *BartNode[V] (internal subnodes). +// The path slice and depth together represent the byte-wise path +// from the root to the current node; depth is incremented for each recursion. +// The is4 flag controls IPv4/IPv6 formatting used by dump. +func (n *BartNode[V]) DumpRec(w io.Writer, path StridePath, depth int, is4 bool) { + if n == nil || n.IsEmpty() { + return + } + + // dump this node + n.dump(w, path, depth, is4) + + // node may have children, rec-descent down + for addr, child := range n.AllChildren() { + if kid, ok := child.(*BartNode[V]); ok { + path[depth] = addr + kid.DumpRec(w, path, depth+1, is4) + } + } +} + +// dump writes a human-readable representation of the node to `w`. +// It prints the node type, depth, formatted path (IPv4 vs IPv6 controlled by `is4`), +// and bit count, followed by any stored prefixes (and their values when applicable), +// the set of child octets, and any path-compressed leaves or fringe entries. +func (n *BartNode[V]) dump(w io.Writer, path StridePath, depth int, is4 bool) { + bits := depth * strideLen + indent := strings.Repeat(".", depth) + + // printing values if V is not the empty struct{} + printValues := !value.IsEmptyStruct[V]() + + // node type with depth and octet path and bits. + fmt.Fprintf(w, "\n%s[%s] depth: %d path: [%s] / %d\n", + indent, n.hasType(), depth, ipStridePath(path, depth, is4), bits) + + if nPfxCount := n.PrefixCount(); nPfxCount != 0 { + var buf [256]uint8 + allIndices := n.Prefixes.AsSlice(&buf) + + // print the baseIndices for this node. + fmt.Fprintf(w, "%sindexs(#%d): %v\n", indent, nPfxCount, allIndices) + + // print the prefixes for this node + fmt.Fprintf(w, "%sprefxs(#%d):", indent, nPfxCount) + + for _, idx := range allIndices { + pfx := CidrFromPath(path, depth, is4, idx) + fmt.Fprintf(w, " %s", pfx) + } + + fmt.Fprintln(w) + + // skip printing values if V is zero-sized + if printValues { + + // print the values for this node + fmt.Fprintf(w, "%svalues(#%d):", indent, nPfxCount) + + for _, idx := range allIndices { + val := n.MustGetPrefix(idx) + fmt.Fprintf(w, " %#v", val) + } + + fmt.Fprintln(w) + } + } + + if cc := n.ChildCount(); cc != 0 { + allAddrs := make([]uint8, 0, cc) + childAddrs := make([]uint8, 0, cc) + leafAddrs := make([]uint8, 0, cc) + fringeAddrs := make([]uint8, 0, cc) + + // the node has recursive child nodes or path-compressed leaves + for addr, child := range n.AllChildren() { + allAddrs = append(allAddrs, addr) + + switch child.(type) { + case *BartNode[V]: + childAddrs = append(childAddrs, addr) + continue + + case *FringeNode[V]: + fringeAddrs = append(fringeAddrs, addr) + + case *LeafNode[V]: + leafAddrs = append(leafAddrs, addr) + + default: + panic("logic error, wrong node type") + } + } + + // print the children for this node. + fmt.Fprintf(w, "%soctets(#%d): %v\n", indent, len(allAddrs), allAddrs) + + if leafCount := len(leafAddrs); leafCount > 0 { + // print the pathcomp prefixes for this node + fmt.Fprintf(w, "%sleaves(#%d):", indent, leafCount) + + for _, addr := range leafAddrs { + kid := n.MustGetChild(addr).(*LeafNode[V]) + + // skip printing values if V is zero-sized + if printValues { + fmt.Fprintf(w, " %s:{%s, %v}", addrFmt(addr, is4), kid.Prefix, kid.Value) + } else { + fmt.Fprintf(w, " %s:{%s}", addrFmt(addr, is4), kid.Prefix) + } + } + + fmt.Fprintln(w) + } + + if fringeCount := len(fringeAddrs); fringeCount > 0 { + // print the pathcomp prefixes for this node + fmt.Fprintf(w, "%sfringe(#%d):", indent, fringeCount) + + for _, addr := range fringeAddrs { + fringePfx := CidrForFringe(path[:], depth, is4, addr) + + kid := n.MustGetChild(addr).(*FringeNode[V]) + + // skip printing values if V is zero-sized + if printValues { + fmt.Fprintf(w, " %s:{%s, %v}", addrFmt(addr, is4), fringePfx, kid.Value) + } else { + fmt.Fprintf(w, " %s:{%s}", addrFmt(addr, is4), fringePfx) + } + } + + fmt.Fprintln(w) + } + + if childCount := len(childAddrs); childCount > 0 { + // print the next child + fmt.Fprintf(w, "%schilds(#%d):", indent, childCount) + + for _, addr := range childAddrs { + fmt.Fprintf(w, " %s", addrFmt(addr, is4)) + } + + fmt.Fprintln(w) + } + + } +} + +// DumpString traverses the trie to the node at the specified depth along the given +// octet path and returns its string representation via Dump. +// +// If the path is invalid or encounters an unexpected node type during traversal, +// it returns an error message string instead. +// +// Parameters: +// - octets: The path of octets to follow from the root +// - depth: Target depth to reach before dumping (0-based byte index) +// - is4: True for IPv4 formatting, false for IPv6 +// +// Returns a formatted string representation of the target node or an error message. +func (n *BartNode[V]) DumpString(octets []uint8, depth int, is4 bool) string { + path := StridePath{} + copy(path[:], octets) + + buf := new(strings.Builder) + for i := range depth { + anyKid, ok := n.GetChild(path[i]) + if !ok { + return fmt.Sprintf("ERROR: kid for %v[%d] is NOT set in node\n", octets, i) + } + + kid, ok := anyKid.(*BartNode[V]) + if !ok { + return fmt.Sprintf("ERROR: kid for %v[%d] is NO %s\n", octets, i, "BartNode[V]") + } + + // traverse + n = kid + } + + n.dump(buf, path, depth, is4) + return buf.String() +} + +// hasType classifies the given node into one of the nodeType values. +// +// It inspects immediate statistics (prefix count, child count, node, leaf and +// fringe counts) for the node and returns: +// - nullNode: no prefixes and no children +// - stopNode: has children but no subnodes (nodes == 0) +// - halfNode: contains at least one leaf or fringe and also has subnodes, but +// no prefixes +// - fullNode: has prefixes and also has subnodes +// - pathNode: has subnodes only (no prefixes, leaves, or fringes) +// +// The order of these checks is significant to ensure the correct classification. +func (n *BartNode[V]) hasType() nodeType { + s := n.Stats() + + // the order is important + switch { + case s.Prefixes == 0 && s.Children == 0: + return nullNode + case s.SubNodes == 0: + return stopNode + case (s.Leaves > 0 || s.Fringes > 0) && s.SubNodes > 0 && s.Prefixes == 0: + return halfNode + case (s.Prefixes > 0 || s.Leaves > 0 || s.Fringes > 0) && s.SubNodes > 0: + return fullNode + case (s.Prefixes == 0 && s.Leaves == 0 && s.Fringes == 0) && s.SubNodes > 0: + return pathNode + default: + panic(fmt.Sprintf("UNREACHABLE: pfx: %d, chld: %d, node: %d, leaf: %d, fringe: %d", + s.Prefixes, s.Children, s.SubNodes, s.Leaves, s.Fringes)) + } +} + +// Stats returns immediate statistics for n: counts of prefixes and children, +// and a classification of each child into nodes, leaves, or fringes. +// It inspects only the direct children of n (not the whole subtree). +// Panics if a child has an unexpected concrete type. +func (n *BartNode[V]) Stats() (s StatsT) { + s.Prefixes = n.PrefixCount() + s.Children = n.ChildCount() + + for _, child := range n.AllChildren() { + switch child.(type) { + case *BartNode[V]: + s.SubNodes++ + + case *FringeNode[V]: + s.Fringes++ + + case *LeafNode[V]: + s.Leaves++ + + default: + panic("logic error, wrong node type") + } + } + + return s +} + +// StatsRec returns aggregated statistics for the subtree rooted at n. +// +// It walks the node tree recursively and sums immediate counts (prefixes and +// child slots) plus the number of nodes, leaves, and fringe nodes in the +// subtree. If n is nil or empty, a zeroed stats is returned. The returned +// SubNodes count includes the current node. The function will panic if a child +// has an unexpected concrete type. +func (n *BartNode[V]) StatsRec() (s StatsT) { + if n == nil || n.IsEmpty() { + return s + } + + s.Prefixes = n.PrefixCount() + s.Children = n.ChildCount() + s.SubNodes = 1 // this node + s.Leaves = 0 + s.Fringes = 0 + + for _, child := range n.AllChildren() { + switch kid := child.(type) { + case *BartNode[V]: + // rec-descent + rs := kid.StatsRec() + + s.Prefixes += rs.Prefixes + s.Children += rs.Children + s.SubNodes += rs.SubNodes + s.Leaves += rs.Leaves + s.Fringes += rs.Fringes + + case *FringeNode[V]: + s.Fringes++ + + case *LeafNode[V]: + s.Leaves++ + + default: + panic("logic error, wrong node type") + } + } + + return s +} + +// FprintRec recursively prints a hierarchical CIDR tree representation +// starting from this node to the provided writer. The output shows the +// routing table structure in human-readable format for debugging and analysis. +func (n *BartNode[V]) FprintRec(w io.Writer, parent TrieItem[V], pad string) error { + // recursion stop condition + if n == nil || n.IsEmpty() { + return nil + } + + // get direct covered childs for this parent ... + directItems := n.DirectItemsRec(parent.Idx, parent.Path, parent.Depth, parent.Is4) + + // sort them by netip.Prefix, not by baseIndex + slices.SortFunc(directItems, func(a, b TrieItem[V]) int { + return CmpPrefix(a.Cidr, b.Cidr) + }) + + // printing values if V is not the empty struct{} + printValues := !value.IsEmptyStruct[V]() + + // for all direct item under this node ... + for i, item := range directItems { + // symbols used in tree + glyph := "├─ " + space := "│ " + + // ... treat last kid special + if i == len(directItems)-1 { + glyph = "└─ " + space = " " + } + + var err error + // val is the empty struct, don't print it + if printValues { + _, err = fmt.Fprintf(w, "%s%s (%v)\n", pad+glyph, item.Cidr, item.Val) + } else { + // skip printing values if V is zero-sized + _, err = fmt.Fprintf(w, "%s%s\n", pad+glyph, item.Cidr) + } + + if err != nil { + return err + } + + // rec-descent with this item as parent + nextNode, _ := item.Node.(*BartNode[V]) + if err = nextNode.FprintRec(w, item, pad+space); err != nil { + return err + } + } + + return nil +} + +// DirectItemsRec, returns the direct covered items by parent. +// It's a complex recursive function, you have to know the data structure +// by heart to understand this function! +func (n *BartNode[V]) DirectItemsRec(parentIdx uint8, path StridePath, depth int, is4 bool) (directItems []TrieItem[V]) { + // recursion stop condition + if n == nil || n.IsEmpty() { + return nil + } + + // prefixes: + // for all idx's (prefixes mapped by baseIndex) in this node + // do a longest-prefix-match + for idx, val := range n.AllIndices() { + // tricky part, skip self + // test with next possible lpm (idx>>1), it's a complete binary tree + nextIdx := idx >> 1 + + // fast skip, lpm not possible + if nextIdx < parentIdx { + continue + } + + // do a longest-prefix-match + lpm, _, _ := n.LookupIdx(nextIdx) + + // be aware, 0 is here a possible value for parentIdx and lpm (if not found) + if lpm == parentIdx { + // prefix is directly covered by parent + + item := TrieItem[V]{ + Node: n, + Is4: is4, + Path: path, + Depth: depth, + Idx: idx, + // get the prefix back from trie + Cidr: CidrFromPath(path, depth, is4, idx), + Val: val, + } + + directItems = append(directItems, item) + } + } + + // children: + for addr, child := range n.AllChildren() { + hostIdx := art.OctetToIdx(addr) + + // do a longest-prefix-match + lpm, _, _ := n.LookupIdx(hostIdx) + + // be aware, 0 is here a possible value for parentIdx and lpm (if not found) + if lpm == parentIdx { + // child is directly covered by parent + switch kid := child.(type) { + case *BartNode[V]: // traverse rec-descent, call with next child node, + // next trie level, set parentIdx to 0, adjust path and depth + path[depth] = addr + directItems = append(directItems, kid.DirectItemsRec(0, path, depth+1, is4)...) + + case *LeafNode[V]: // path-compressed child, stops recursion for this child + item := TrieItem[V]{ + Node: nil, + Is4: is4, + Cidr: kid.Prefix, + Val: kid.Value, + } + directItems = append(directItems, item) + + case *FringeNode[V]: // path-compressed fringe, stops recursion for this child + item := TrieItem[V]{ + Node: nil, + Is4: is4, + // get the prefix back from trie + Cidr: CidrForFringe(path[:], depth, is4, addr), + Val: kid.Value, + } + directItems = append(directItems, item) + + default: + panic("logic error, wrong node type") + } + } + } + + return directItems +} + +// UnionRec recursively merges another node o into the receiver node n. +// +// All prefix and child entries from o are cloned and inserted into n. +// If a prefix already exists in n, its value is overwritten by the value from o, +// and the duplicate is counted in the return value. This count can later be used +// to update size-related metadata in the parent trie. +// +// The union handles all possible combinations of child node types (node, leaf, fringe) +// between the two nodes. Structural conflicts are resolved by creating new intermediate +// *BartNode[V] objects and pushing both children further down the trie. Leaves and fringes +// are also recursively relocated as needed to preserve prefix semantics. +// +// The merge operation is destructive on the receiver n, but leaves the source node o unchanged. +// +// Returns the number of duplicate prefixes that were overwritten during merging. +func (n *BartNode[V]) UnionRec(cloneFn func(V) V, o *BartNode[V], depth int) (duplicates int) { + if cloneFn == nil { + cloneFn = func(v V) V { return v } + } + + buf := [256]uint8{} + + // for all prefixes in other node do ... + for _, oIdx := range o.Prefixes.AsSlice(&buf) { + // clone/copy the value from other node at idx + val := o.MustGetPrefix(oIdx) + clonedVal := cloneFn(val) + + // insert/overwrite cloned value from o into n + if n.InsertPrefix(oIdx, clonedVal) { + // this prefix is duplicate in n and o + duplicates++ + } + } + + // for all child addrs in other node do ... + for _, addr := range o.Children.AsSlice(&buf) { + otherChild := o.MustGetChild(addr) + thisChild, thisExists := n.GetChild(addr) + + // Use helper function to handle all 4x3 combinations + duplicates += n.handleMatrix(cloneFn, thisExists, thisChild, otherChild, addr, depth) + } + + return duplicates +} + +// UnionRecPersist is similar to unionRec but performs an immutable union of nodes. +func (n *BartNode[V]) UnionRecPersist(cloneFn func(V) V, o *BartNode[V], depth int) (duplicates int) { + if cloneFn == nil { + cloneFn = func(v V) V { return v } + } + + buf := [256]uint8{} + + // for all prefixes in other node do ... + for _, oIdx := range o.Prefixes.AsSlice(&buf) { + // clone/copy the value from other node + val := o.MustGetPrefix(oIdx) + clonedVal := cloneFn(val) + + // insert/overwrite cloned value from o into n + if exists := n.InsertPrefix(oIdx, clonedVal); exists { + // this prefix is duplicate in n and o + duplicates++ + } + } + + // for all child addrs in other node do ... + for _, addr := range o.Children.AsSlice(&buf) { + otherChild := o.MustGetChild(addr) + thisChild, thisExists := n.GetChild(addr) + + // Use helper function to handle all 4x3 combinations + duplicates += n.handleMatrixPersist(cloneFn, thisExists, thisChild, otherChild, addr, depth) + } + + return duplicates +} + +// handleMatrix, 12 possible combinations to union this child and other child +// +// THIS, OTHER: (always clone the other kid!) +// -------------- +// NULL, node <-- insert node at addr +// NULL, leaf <-- insert leaf at addr +// NULL, fringe <-- insert fringe at addr +// +// node, node <-- union rec-descent with node +// node, leaf <-- insert leaf at depth+1 +// node, fringe <-- insert fringe at depth+1 +// +// leaf, node <-- insert new node, push this leaf down, union rec-descent +// leaf, leaf <-- insert new node, push both leaves down (!first check equality) +// leaf, fringe <-- insert new node, push this leaf and fringe down +// +// fringe, node <-- insert new node, push this fringe down, union rec-descent +// fringe, leaf <-- insert new node, push this fringe down, insert other leaf at depth+1 +// fringe, fringe <-- just overwrite value +func (n *BartNode[V]) handleMatrix(cloneFn func(V) V, thisExists bool, thisChild, otherChild any, addr uint8, depth int) int { + // Do ALL type assertions upfront - reduces line noise + var ( + thisNode, thisIsNode = thisChild.(*BartNode[V]) + thisLeaf, thisIsLeaf = thisChild.(*LeafNode[V]) + thisFringe, thisIsFringe = thisChild.(*FringeNode[V]) + + otherNode, otherIsNode = otherChild.(*BartNode[V]) + otherLeaf, otherIsLeaf = otherChild.(*LeafNode[V]) + otherFringe, otherIsFringe = otherChild.(*FringeNode[V]) + ) + + // just insert cloned child at this empty slot + if !thisExists { + switch { + case otherIsNode: + n.InsertChild(addr, otherNode.CloneRec(cloneFn)) + case otherIsLeaf: + n.InsertChild(addr, &LeafNode[V]{Prefix: otherLeaf.Prefix, Value: cloneFn(otherLeaf.Value)}) + case otherIsFringe: + n.InsertChild(addr, &FringeNode[V]{Value: cloneFn(otherFringe.Value)}) + default: + panic("logic error, wrong node type") + } + return 0 + } + + // Case 1: Special cases that DON'T need a new node + + // Special case: fringe + fringe -> just overwrite value + if thisIsFringe && otherIsFringe { + thisFringe.Value = cloneFn(otherFringe.Value) + return 1 + } + + // Special case: leaf + leaf with same prefix -> just overwrite value + if thisIsLeaf && otherIsLeaf && thisLeaf.Prefix == otherLeaf.Prefix { + thisLeaf.Value = cloneFn(otherLeaf.Value) + return 1 + } + + // Case 2: thisChild is already a node - insert into it, no new node needed + if thisIsNode { + switch { + case otherIsNode: + return thisNode.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if thisNode.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if thisNode.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong node type") + } + } + + // Case 3: All remaining cases need a new node + // (thisChild is leaf or fringe, and we didn't hit the special cases above) + + nc := new(BartNode[V]) + + // Push existing child down into new node + switch { + case thisIsLeaf: + nc.Insert(thisLeaf.Prefix, thisLeaf.Value, depth+1) + case thisIsFringe: + nc.InsertPrefix(1, thisFringe.Value) + default: + panic("logic error, unexpected this child type") + } + + // Replace child with new node + n.InsertChild(addr, nc) + + // Now handle other child + switch { + case otherIsNode: + return nc.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if nc.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if nc.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong other node type") + } +} + +// handleMatrixPersist, 12 possible combinations to union this child and other child +// +// THIS, OTHER: (always clone the other kid!) +// -------------- +// NULL, node <-- insert node at addr +// NULL, leaf <-- insert leaf at addr +// NULL, fringe <-- insert fringe at addr +// +// node, node <-- union rec-descent with node +// node, leaf <-- insert leaf at depth+1 +// node, fringe <-- insert fringe at depth+1 +// +// leaf, node <-- insert new node, push this leaf down, union rec-descent +// leaf, leaf <-- insert new node, push both leaves down (!first check equality) +// leaf, fringe <-- insert new node, push this leaf and fringe down +// +// fringe, node <-- insert new node, push this fringe down, union rec-descent +// fringe, leaf <-- insert new node, push this fringe down, insert other leaf at depth+1 +// fringe, fringe <-- just overwrite value +func (n *BartNode[V]) handleMatrixPersist(cloneFn func(V) V, thisExists bool, thisChild, otherChild any, addr uint8, depth int) int { + // Do ALL type assertions upfront - reduces line noise + var ( + thisNode, thisIsNode = thisChild.(*BartNode[V]) + thisLeaf, thisIsLeaf = thisChild.(*LeafNode[V]) + thisFringe, thisIsFringe = thisChild.(*FringeNode[V]) + + otherNode, otherIsNode = otherChild.(*BartNode[V]) + otherLeaf, otherIsLeaf = otherChild.(*LeafNode[V]) + otherFringe, otherIsFringe = otherChild.(*FringeNode[V]) + ) + + // just insert cloned child at this empty slot + if !thisExists { + switch { + case otherIsNode: + n.InsertChild(addr, otherNode.CloneRec(cloneFn)) + case otherIsLeaf: + n.InsertChild(addr, &LeafNode[V]{Prefix: otherLeaf.Prefix, Value: cloneFn(otherLeaf.Value)}) + case otherIsFringe: + n.InsertChild(addr, &FringeNode[V]{Value: cloneFn(otherFringe.Value)}) + default: + panic("logic error, wrong node type") + } + return 0 + } + + // Case 1: Special cases that DON'T need a new node + + // Special case: fringe + fringe -> just overwrite value + if thisIsFringe && otherIsFringe { + thisFringe.Value = cloneFn(otherFringe.Value) + return 1 + } + + // Special case: leaf + leaf with same prefix -> just overwrite value + if thisIsLeaf && otherIsLeaf && thisLeaf.Prefix == otherLeaf.Prefix { + thisLeaf.Value = cloneFn(otherLeaf.Value) + return 1 + } + + // Case 2: thisChild is already a node - clone this node, insert into it + if thisIsNode { + // CLONE the node + + // thisNode points now to cloned kid + thisNode = thisNode.CloneFlat(cloneFn) + + // replace kid with cloned thisKid + n.InsertChild(addr, thisNode) + + switch { + case otherIsNode: + return thisNode.UnionRecPersist(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if thisNode.InsertPersist(cloneFn, otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if thisNode.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong node type") + } + } + + // Case 3: All remaining cases need a new node + // (thisChild is leaf or fringe, and we didn't hit the special cases above) + + nc := new(BartNode[V]) + + // Push existing child down into new node + switch { + case thisIsLeaf: + nc.Insert(thisLeaf.Prefix, thisLeaf.Value, depth+1) + case thisIsFringe: + nc.InsertPrefix(1, thisFringe.Value) + default: + panic("logic error, unexpected this child type") + } + + // Replace child with new node + n.InsertChild(addr, nc) + + // Now handle other child + switch { + case otherIsNode: + return nc.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if nc.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if nc.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong other node type") + } +} + +// AllRec recursively traverses the trie starting at the current node, +// applying the provided yield function to every stored prefix and value. +// +// For each route entry (prefix and value), yield is invoked. If yield returns false, +// the traversal stops immediately, and false is propagated upwards, +// enabling early termination. +// +// The function handles all prefix entries in the current node, as well as any children - +// including sub-nodes, leaf nodes with full prefixes, and fringe nodes +// representing path-compressed prefixes. IP prefix reconstruction is performed on-the-fly +// from the current path and depth. +// +// The traversal order is not defined. This implementation favors simplicity +// and runtime efficiency over consistency of iteration sequence. +func (n *BartNode[V]) AllRec(path StridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { + var buf [256]uint8 + for _, idx := range n.Prefixes.AsSlice(&buf) { + cidr := CidrFromPath(path, depth, is4, idx) + val := n.MustGetPrefix(idx) + + // callback for this prefix and val + if !yield(cidr, val) { + // early exit + return false + } + } + + // for all children (nodes and leaves) in this node do ... + for _, addr := range n.Children.AsSlice(&buf) { + anyKid := n.MustGetChild(addr) + switch kid := anyKid.(type) { + case *BartNode[V]: + // rec-descent with this node + path[depth] = addr + if !kid.AllRec(path, depth+1, is4, yield) { + // early exit + return false + } + case *LeafNode[V]: + // callback for this leaf + if !yield(kid.Prefix, kid.Value) { + // early exit + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// AllRecSorted recursively traverses the trie in prefix-sorted order and applies +// the given yield function to each stored prefix and value. +// +// Unlike AllRec, this implementation ensures that route entries are visited in +// canonical prefix sort order. To achieve this, +// both the prefixes and children of the current node are gathered, sorted, +// and then interleaved during traversal based on logical octet positioning. +// +// The function first sorts relevant entries by their prefix index and address value, +// using a comparison function that ranks prefixes according to their mask length and position. +// Then it walks the trie, always yielding child entries that fall before the current prefix, +// followed by the prefix itself. Remaining children are processed once all prefixes have been visited. +// +// Prefixes are reconstructed on-the-fly from the traversal path, and iteration includes all child types: +// inner nodes (recursive descent), leaf nodes, and fringe (compressed) prefixes. +// +// The order is stable and predictable, making the function suitable for use cases +// like table exports, comparisons or serialization. +// +// Parameters: +// - path: the current traversal path through the trie +// - depth: current depth in the trie (0-based) +// - is4: true for IPv4 processing, false for IPv6 +// - yield: callback function invoked for each prefix/value pair +// +// Returns false if yield function requests early termination. +func (n *BartNode[V]) AllRecSorted(path StridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { + // get slice of all child octets, sorted by addr + var childBuf [256]uint8 + allChildAddrs := n.Children.AsSlice(&childBuf) + + // get slice of all indexes, sorted by idx + var idxBuf [256]uint8 + allIndices := n.Prefixes.AsSlice(&idxBuf) + + // sort indices in CIDR sort order + slices.SortFunc(allIndices, CmpIndexRank) + + childCursor := 0 + + // yield indices and children in CIDR sort order + for _, pfxIdx := range allIndices { + pfxOctet, _ := art.IdxToPfx(pfxIdx) + + // yield all children before idx + for j := childCursor; j < len(allChildAddrs); j++ { + childAddr := allChildAddrs[j] + + if childAddr >= pfxOctet { + break + } + + // yield the node (rec-descent) or leaf + anyKid := n.MustGetChild(childAddr) + switch kid := anyKid.(type) { + case *BartNode[V]: + path[depth] = childAddr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, childAddr) + if !yield(fringePfx, kid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + + childCursor++ + } + + // yield the prefix for this idx + cidr := CidrFromPath(path, depth, is4, pfxIdx) + // n.prefixes.Items[i] not possible after sorting allIndices + if !yield(cidr, n.MustGetPrefix(pfxIdx)) { + return false + } + } + + // yield the rest of leaves and nodes (rec-descent) + for j := childCursor; j < len(allChildAddrs); j++ { + addr := allChildAddrs[j] + anyKid := n.MustGetChild(addr) + switch kid := anyKid.(type) { + case *BartNode[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + if !yield(fringePfx, kid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// EachLookupPrefix performs a hierarchical lookup of all matching prefixes +// in the current node’s 8-bit stride-based prefix table. +// +// The function walks up the trie-internal complete binary tree (CBT), +// testing each possible prefix length mask (in decreasing order of specificity), +// and invokes the yield function for every matching entry. +// +// The given idx refers to the position for this stride's prefix and is used +// to derive a backtracking path through the CBT by repeatedly halving the index. +// At each step, if a prefix exists in the table, its corresponding CIDR is +// reconstructed and yielded. If yield returns false, traversal stops early. +// +// This function is intended for internal use during supernet traversal and +// does not descend the trie further. +func (n *BartNode[V]) EachLookupPrefix(ip netip.Addr, depth int, pfxIdx uint8, yield func(netip.Prefix, V) bool) (ok bool) { + for ; pfxIdx > 0; pfxIdx >>= 1 { + if n.Prefixes.Test(pfxIdx) { + val := n.MustGetPrefix(pfxIdx) + + // get the CIDR back + _, pfxLen := art.IdxToPfx(pfxIdx) + cidr, _ := ip.Prefix(depth<<3 + int(pfxLen)) + + if !yield(cidr, val) { + return false + } + } + } + + return true +} + +// EachSubnet yields all prefix entries and child nodes covered by a given parent prefix, +// sorted in natural CIDR order, within the current node. +// +// The function iterates through all prefixes and children from the node’s stride tables. +// Only entries that fall within the address range defined by the parent prefix index (pfxIdx) +// are included. Matching entries are buffered, sorted, and passed through to the yield function. +// +// Child entries (nodes, leaves, fringes) that fall under the covered address range +// are processed recursively via AllRecSorted to ensure sorted traversal. +// +// This function is intended for internal use by Subnets(), and it assumes the +// current node is positioned at the point in the trie corresponding to the parent prefix. +func (n *BartNode[V]) EachSubnet(octets []byte, depth int, is4 bool, pfxIdx uint8, yield func(netip.Prefix, V) bool) bool { + // octets as array, needed below more than once + var path StridePath + copy(path[:], octets) + + pfxFirstAddr, pfxLastAddr := art.IdxToRange(pfxIdx) + + allCoveredIndices := make([]uint8, 0, n.PrefixCount()) + + var buf [256]uint8 + for _, idx := range n.Prefixes.AsSlice(&buf) { + thisFirstAddr, thisLastAddr := art.IdxToRange(idx) + + if thisFirstAddr >= pfxFirstAddr && thisLastAddr <= pfxLastAddr { + allCoveredIndices = append(allCoveredIndices, idx) + } + } + + // sort indices in CIDR sort order + slices.SortFunc(allCoveredIndices, CmpIndexRank) + + // 2. collect all covered child addrs by prefix + + allCoveredChildAddrs := make([]uint8, 0, n.ChildCount()) + for _, addr := range n.Children.AsSlice(&buf) { + if addr >= pfxFirstAddr && addr <= pfxLastAddr { + allCoveredChildAddrs = append(allCoveredChildAddrs, addr) + } + } + + // 3. yield covered indices, path-compressed prefixes + // and children in CIDR sort order + + addrCursor := 0 + + // yield indices and children in CIDR sort order + for _, pfxIdx := range allCoveredIndices { + pfxOctet, _ := art.IdxToPfx(pfxIdx) + + // yield all children before idx + for j := addrCursor; j < len(allCoveredChildAddrs); j++ { + addr := allCoveredChildAddrs[j] + if addr >= pfxOctet { + break + } + + // yield the node or leaf? + switch kid := n.MustGetChild(addr).(type) { + case *BartNode[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + + addrCursor++ + } + + // yield the prefix for this idx + cidr := CidrFromPath(path, depth, is4, pfxIdx) + // n.prefixes.Items[i] not possible after sorting allIndices + if !yield(cidr, n.MustGetPrefix(pfxIdx)) { + return false + } + } + + // yield the rest of leaves and nodes (rec-descent) + for _, addr := range allCoveredChildAddrs[addrCursor:] { + // yield the node or leaf? + switch kid := n.MustGetChild(addr).(type) { + case *BartNode[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// Supernets yields all supernet prefixes of pfx that exist in the trie, +// in reverse order (most-specific first, least-specific last). +// +// It traverses upward from the given prefix toward the root, collecting +// matching prefixes along the path. The traversal uses a stack to yield +// results in reverse order, so that more-specific supernets appear before +// less-specific ones. +// +// The function handles all node types (internal nodes, leaves, and fringes) +// and stops early if the yield callback returns false. +// +// Parameters: +// - pfx: The prefix for which to find supernets +// - yield: Callback function invoked for each supernet prefix/value pair +// +// The yield function receives prefix/value pairs and returns false to stop +// the iteration early. +func (n *BartNode[V]) Supernets(pfx netip.Prefix, yield func(netip.Prefix, V) bool) { + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // stack of the traversed nodes for reverse ordering of supernets + stack := [MaxTreeDepth]*BartNode[V]{} + + // run variable, used after for loop + var depth int + var octet byte + + // find last node along this octet path +LOOP: + for depth, octet = range octets { + // stepped one past the last stride of interest; back up to last and exit + if depth > strideCount { + depth-- + break + } + // push current node on stack + stack[depth] = n + + // descend down the trie + if !n.Children.Test(octet) { + break LOOP + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *BartNode[V]: + n = kid + continue LOOP // descend down to next trie level + + case *LeafNode[V]: + if kid.Prefix.Bits() > pfx.Bits() { + break LOOP + } + + if kid.Prefix.Overlaps(pfx) { + if !yield(kid.Prefix, kid.Value) { + // early exit + return + } + } + // end of trie along this octets path + break LOOP + + case *FringeNode[V]: + fringePfx := CidrForFringe(octets, depth, is4, octet) + if fringePfx.Bits() > pfx.Bits() { + break LOOP + } + + if fringePfx.Overlaps(pfx) { + if !yield(fringePfx, kid.Value) { + // early exit + return + } + } + // end of trie along this octets path + break LOOP + + default: + panic("logic error, wrong node type") + } + } + + // start backtracking, unwind the stack + for ; depth >= 0; depth-- { + n = stack[depth] + + // only the lastOctet may have a different prefix len + // all others are just host routes + var idx uint8 + octet = octets[depth] + // Last “octet” from prefix + // Note: For /32 and /128, depth never reaches strideCount (4/16), + if depth == strideCount { + idx = art.PfxToIdx(octet, modBits) + } else { + idx = art.OctetToIdx(octet) + } + + // micro benchmarking, skip if there is no match + if !n.Contains(idx) { + continue + } + + // yield all the matching prefixes, not just the lpm + if !n.EachLookupPrefix(ip, depth, idx, yield) { + // early exit + return + } + } +} + +// Subnets yields all subnet prefixes covered by pfx that exist in the trie, +// in CIDR sort order. +// +// It first locates the trie node corresponding to pfx, then recursively +// yields all prefixes and child entries contained within that subtree. +// The traversal uses sorted iteration to maintain canonical CIDR ordering. +// +// The function handles various node types (internal nodes, leaves, and fringes) +// and uses EachSubnet and AllRecSorted for sorted traversal of covered prefixes. +// +// Parameters: +// - pfx: The parent prefix whose subnets should be yielded +// - yield: Callback function invoked for each subnet prefix/value pair +// +// The yield function receives prefix/value pairs and returns false to stop +// the iteration early. If pfx doesn't exist in the trie, no prefixes are yielded. +func (n *BartNode[V]) Subnets(pfx netip.Prefix, yield func(netip.Prefix, V) bool) { + // values derived from pfx + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // find the trie node + for depth, octet := range octets { + // Last “octet” from prefix + // Note: For /32 and /128, depth never reaches strideCount (4/16), + // so those are handled below via the fringe/leaf path. + if depth == strideCount { + idx := art.PfxToIdx(octet, modBits) + n.EachSubnet(octets, depth, is4, idx, yield) + return + } + + if !n.Children.Test(octet) { + return + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *BartNode[V]: + n = kid + continue // descend down to next trie level + + case *LeafNode[V]: + if pfx.Bits() <= kid.Prefix.Bits() && pfx.Overlaps(kid.Prefix) { + yield(kid.Prefix, kid.Value) + } + return // immediate return + + case *FringeNode[V]: + // get the LPM prefix back from ip and depth + // it's a fringe, bits are always /8, /16, /24, ... + fringePfx, _ := ip.Prefix((depth + 1) << 3) + + if pfx.Bits() <= fringePfx.Bits() && pfx.Overlaps(fringePfx) { + yield(fringePfx, kid.Value) + } + return // immediate return + + default: + panic("logic error, wrong node type") + } + } +} + +// Overlaps recursively compares two trie nodes and returns true +// if any of their prefixes or descendants overlap. +// +// The implementation checks for: +// 1. Direct overlapping prefixes on this node level +// 2. Prefixes in one node overlapping with children in the other +// 3. Matching child addresses in both nodes, which are recursively compared +// +// All 12 possible type combinations for child entries (node, leaf, fringe) are supported. +// +// The function is optimized for early exit on first match and uses heuristics to +// choose between set-based and loop-based matching for performance. +func (n *BartNode[V]) Overlaps(o *BartNode[V], depth int) bool { + nPfxCount := n.PrefixCount() + oPfxCount := o.PrefixCount() + + nChildCount := n.ChildCount() + oChildCount := o.ChildCount() + + // ############################## + // 1. Test if any routes overlaps + // ############################## + + // full cross check + if nPfxCount > 0 && oPfxCount > 0 { + if n.OverlapsRoutes(o) { + return true + } + } + + // #################################### + // 2. Test if routes overlaps any child + // #################################### + + // swap nodes to help chance on its way, + // if the first call to expensive overlapsChildrenIn() is already true, + // if both orders are false it doesn't help either + if nChildCount > oChildCount { + n, o = o, n + + nPfxCount = n.PrefixCount() + oPfxCount = o.PrefixCount() + + nChildCount = n.ChildCount() + oChildCount = o.ChildCount() + } + + if nPfxCount > 0 && oChildCount > 0 { + if n.OverlapsChildrenIn(o) { + return true + } + } + + // symmetric reverse + if oPfxCount > 0 && nChildCount > 0 { + if o.OverlapsChildrenIn(n) { + return true + } + } + + // ############################################ + // 3. children with same octet in nodes n and o + // ############################################ + + // stop condition, n or o have no children + if nChildCount == 0 || oChildCount == 0 { + return false + } + + // stop condition, no child with identical octet in n and o + if !n.Children.Intersects(&o.Children.BitSet256) { + return false + } + + return n.OverlapsSameChildren(o, depth) +} + +// OverlapsRoutes compares the prefix sets of two nodes (n and o). +// +// It first checks for direct bitset intersection (identical indices), +// then walks both prefix sets using the Contains method to detect if any +// of the n-prefixes is contained in o, or vice versa. +func (n *BartNode[V]) OverlapsRoutes(o *BartNode[V]) bool { + // some prefixes are identical, trivial overlap + if n.Prefixes.Intersects(&o.Prefixes.BitSet256) { + return true + } + + // get the lowest idx (biggest prefix) + nFirstIdx, _ := n.Prefixes.FirstSet() + oFirstIdx, _ := o.Prefixes.FirstSet() + + // start with other min value + nIdx := oFirstIdx + oIdx := nFirstIdx + + nOK := true + oOK := true + + // zip, range over n and o together to help chance on its way + for nOK || oOK { + if nOK { + // does any route in o overlap this prefix from n + if nIdx, nOK = n.Prefixes.NextSet(nIdx); nOK { + if o.Contains(nIdx) { + return true + } + + if nIdx == 255 { + // stop, don't overflow uint8! + nOK = false + } else { + nIdx++ + } + } + } + + if oOK { + // does any route in n overlap this prefix from o + if oIdx, oOK = o.Prefixes.NextSet(oIdx); oOK { + if n.Contains(oIdx) { + return true + } + + if oIdx == 255 { + // stop, don't overflow uint8! + oOK = false + } else { + oIdx++ + } + } + } + } + + return false +} + +// OverlapsChildrenIn checks whether the prefixes in node n +// overlap with any children (by address range) in node o. +// +// Uses bitset intersection or manual iteration heuristically, +// depending on prefix and child count. +// +// Bitset-based matching uses precomputed coverage tables +// to avoid per-address looping. This is critical for high fan-out nodes. +func (n *BartNode[V]) OverlapsChildrenIn(o *BartNode[V]) bool { + pfxCount := n.PrefixCount() + childCount := o.ChildCount() + + // heuristic: 15 is the crossover point where bitset operations become + // more efficient than iteration, determined by micro benchmarks on typical + // routing table distributions + const overlapsRangeCutoff = 15 + + doRange := childCount < overlapsRangeCutoff || pfxCount > overlapsRangeCutoff + + // do range over, not so many children and maybe too many prefixes for other algo below + var buf [256]uint8 + if doRange { + for _, addr := range o.Children.AsSlice(&buf) { + if n.Contains(art.OctetToIdx(addr)) { + return true + } + } + return false + } + + // do bitset intersection, alloted route table with child octets + // maybe too many children for range-over or not so many prefixes to + // build the alloted routing table from them + + // use allot table with prefixes as bitsets, bitsets are precalculated. + for _, idx := range n.Prefixes.AsSlice(&buf) { + if o.Children.Intersects(&allot.FringeRoutesLookupTbl[idx]) { + return true + } + } + + return false +} + +// OverlapsSameChildren compares all matching child addresses (octets) +// between node n and node o recursively. +// +// For each shared address, the corresponding child nodes (of any type) +// are compared using BartNodeOverlapsTwoChildren, which handles all +// node/leaf/fringe combinations. +func (n *BartNode[V]) OverlapsSameChildren(o *BartNode[V], depth int) bool { + // intersect the child bitsets from n with o + commonChildren := n.Children.Intersection(&o.Children.BitSet256) + + for addr, ok := commonChildren.NextSet(0); ok; { + nChild := n.MustGetChild(addr) + oChild := o.MustGetChild(addr) + + if n.OverlapsTwoChildren(nChild, oChild, depth+1) { + return true + } + + if addr == 255 { + break // Prevent uint8 overflow + } + + addr, ok = commonChildren.NextSet(addr + 1) + } + return false +} + +// OverlapsPrefixAtDepth returns true if any route in the subtree rooted at this node +// overlaps with the given pfx, starting the comparison at the specified depth. +// +// This function supports structural overlap detection even in compressed or sparse +// paths within the trie, including fringe and leaf nodes. Matching is directional: +// it returns true if a route fully covers pfx, or if pfx covers an existing route. +// +// At each step, it checks for visible prefixes and children that may intersect the +// target prefix via stride-based longest-prefix test. The walk terminates early as +// soon as a structural overlap is found. +// +// This function underlies the top-level OverlapsPrefix behavior and handles details of +// trie traversal across varying prefix lengths and compression levels. +func (n *BartNode[V]) OverlapsPrefixAtDepth(pfx netip.Prefix, depth int) bool { + ip := pfx.Addr() + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + for ; depth < len(octets); depth++ { + if depth > strideCount { + break + } + + octet := octets[depth] + + // full octet path in node trie, check overlap with last prefix octet + if depth == strideCount { + return n.OverlapsIdx(art.PfxToIdx(octet, modBits)) + } + + // test if any route overlaps prefix´ so far + // no best match needed, forward tests without backtracking + if n.PrefixCount() != 0 && n.Contains(art.OctetToIdx(octet)) { + return true + } + + if !n.Children.Test(octet) { + return false + } + + // next child, node or leaf + switch kid := n.MustGetChild(octet).(type) { + case *BartNode[V]: + n = kid + continue + + case *LeafNode[V]: + return kid.Prefix.Overlaps(pfx) + + case *FringeNode[V]: + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable: " + pfx.String()) +} + +// OverlapsIdx returns true if the given prefix index overlaps with any entry in this node. +// +// The overlap detection considers three categories: +// +// 1. Whether any stored prefix in this node covers the requested prefix (LPM test) +// 2. Whether the requested prefix covers any stored route in the node +// 3. Whether the requested prefix overlaps with any fringe or child entry +// +// Internally, it leverages precomputed bitsets from the allotment model, +// using fast bitwise set intersections instead of explicit range comparisons. +// This enables high-performance overlap checks on a single stride level +// without descending further into the trie. +func (n *BartNode[V]) OverlapsIdx(idx uint8) bool { + // 1. Test if any route in this node overlaps prefix? + if n.Contains(idx) { + return true + } + + // 2. Test if prefix overlaps any route in this node + if n.Prefixes.Intersects(&allot.PfxRoutesLookupTbl[idx]) { + return true + } + + // 3. Test if prefix overlaps any child in this node + return n.Children.Intersects(&allot.FringeRoutesLookupTbl[idx]) +} + +// OverlapsTwoChildren handles all 3x3 combinations of +// node kinds (node, leaf, fringe). +// +// 3x3 possible different combinations for n and o +// +// node, node --> overlaps rec descent +// node, leaf --> overlapsPrefixAtDepth +// node, fringe --> true +// +// leaf, node --> overlapsPrefixAtDepth +// leaf, leaf --> netip.Prefix.Overlaps +// leaf, fringe --> true +// +// fringe, node --> true +// fringe, leaf --> true +// fringe, fringe --> true +func (n *BartNode[V]) OverlapsTwoChildren(nChild, oChild any, depth int) bool { + // child type detection + nNode, nIsNode := nChild.(*BartNode[V]) + nLeaf, nIsLeaf := nChild.(*LeafNode[V]) + _, nIsFringe := nChild.(*FringeNode[V]) + + oNode, oIsNode := oChild.(*BartNode[V]) + oLeaf, oIsLeaf := oChild.(*LeafNode[V]) + _, oIsFringe := oChild.(*FringeNode[V]) + + // Handle all 9 combinations with a single expression + switch { + // NODE cases + case nIsNode && oIsNode: + return nNode.Overlaps(oNode, depth) + case nIsNode && oIsLeaf: + return nNode.OverlapsPrefixAtDepth(oLeaf.Prefix, depth) + case nIsNode && oIsFringe: + return true + + // LEAF cases + case nIsLeaf && oIsNode: + return oNode.OverlapsPrefixAtDepth(nLeaf.Prefix, depth) + case nIsLeaf && oIsLeaf: + return oLeaf.Prefix.Overlaps(nLeaf.Prefix) + case nIsLeaf && oIsFringe: + return true + + // FRINGE cases + case nIsFringe: + return true // fringe overlaps with everything + + default: + panic("logic error, wrong node type combination") + } +} diff --git a/vendor/github.com/gaissmai/bart/internal/nodes/commonmethods_tmpl.go b/vendor/github.com/gaissmai/bart/internal/nodes/commonmethods_tmpl.go new file mode 100644 index 0000000..6767152 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/nodes/commonmethods_tmpl.go @@ -0,0 +1,2461 @@ +//go:build generate + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +//go:generate ../../scripts/generate-node-methods.sh + +package nodes + +// ### GENERATE DELETE START ### + +// stub code for generator types and methods +// useful for gopls during development, deleted during go generate + +import ( + "fmt" + "io" + "iter" + "net/netip" + "slices" + "strings" + + "github.com/gaissmai/bart/internal/allot" + "github.com/gaissmai/bart/internal/art" + "github.com/gaissmai/bart/internal/bitset" + "github.com/gaissmai/bart/internal/value" +) + +type _NODE_TYPE[V any] struct { + Prefixes struct{ bitset.BitSet256 } + Children struct{ bitset.BitSet256 } +} + +func (n *_NODE_TYPE[V]) IsEmpty() (_ bool) { return } +func (n *_NODE_TYPE[V]) PrefixCount() (_ int) { return } +func (n *_NODE_TYPE[V]) ChildCount() (_ int) { return } +func (n *_NODE_TYPE[V]) MustGetPrefix(uint8) (_ V) { return } +func (n *_NODE_TYPE[V]) MustGetChild(uint8) (_ any) { return } +func (n *_NODE_TYPE[V]) InsertPrefix(uint8, V) (_ bool) { return } +func (n *_NODE_TYPE[V]) DeletePrefix(uint8) (_ bool) { return } +func (n *_NODE_TYPE[V]) GetChild(uint8) (_ any, _ bool) { return } +func (n *_NODE_TYPE[V]) GetPrefix(uint8) (_ V, _ bool) { return } +func (n *_NODE_TYPE[V]) InsertChild(uint8, any) (_ bool) { return } +func (n *_NODE_TYPE[V]) DeleteChild(uint8) (_ bool) { return } +func (n *_NODE_TYPE[V]) CloneRec(func(V) V) (_ *_NODE_TYPE[V]) { return } +func (n *_NODE_TYPE[V]) CloneFlat(func(V) V) (_ *_NODE_TYPE[V]) { return } +func (n *_NODE_TYPE[V]) AllIndices() (seq2 iter.Seq2[uint8, V]) { return } +func (n *_NODE_TYPE[V]) AllChildren() (seq2 iter.Seq2[uint8, any]) { return } +func (n *_NODE_TYPE[V]) Contains(uint8) (_ bool) { return } +func (n *_NODE_TYPE[V]) LookupIdx(uint8) (_ uint8, _ V, _ bool) { return } + +// ### GENERATE DELETE END ### + +// Insert adds or updates a network prefix and its associated value in the trie. +// Traversal begins at the specified byte depth. +// +// The trie utilizes path compression to conserve memory. A prefix is inserted: +// - Uncompressed into a node's prefix table at depth == strideCount. +// - As a path-compressed FringeNode if it qualifies as fringe [IsFringe]. +// - As a path-compressed LeafNode otherwise. +// +// When a new prefix collides with an existing compressed node (Leaf or Fringe), +// Insert resolves the collision by creating a new intermediate node, pushing +// the existing entry down to the next level, and continuing traversal. +// +// Parameters: +// - pfx: The network prefix to insert (must be in canonical/masked form). +// - val: The value to associate with the prefix. +// - depth: The current depth in the trie (0-based byte index). +// +// Returns true if an existing prefix was updated, false if a new insertion occurred. +func (n *_NODE_TYPE[V]) Insert(pfx netip.Prefix, val V, depth int) (exists bool) { + ip := pfx.Addr() // the pfx must be in canonical form + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the prefix's octets. Each depth corresponds to an 8-bit stride. + // We descend through the trie until we either reach the final stride (depth == strideCount) + // or find an empty child slot where we can path-compress the remaining strides. + for ; depth < len(octets); depth++ { + octet := octets[depth] + + // The current depth matches the prefix's stride count, meaning this is the final + // node for this prefix. We insert it directly into this node's prefix table. + if depth == strideCount { + return n.InsertPrefix(art.PfxToIdx(octet, modBits), val) + } + + // No child exists at this octet path. Instead of creating intermediate nodes + // for the remaining strides, we path-compress the rest of the prefix into a single child slot. + if !n.Children.Test(octet) { + // If the prefix is perfectly aligned with the next stride boundary (e.g., /16 at depth 1), + // it acts as a default route for everything below it. We store it as a FringeNode. + // Otherwise, it has trailing bits or crosses boundaries, so we store it as a LeafNode. + if IsFringe(depth, pfxLen) { + return n.InsertChild(octet, NewFringeNode(val)) + } + return n.InsertChild(octet, NewLeafNode(pfx, val)) + } + + // A child already exists at this octet path. Retrieve it to either continue + // our descent along the strides or resolve a structural collision with a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *_NODE_TYPE[V]: + // Standard intermediate node: descend to the next trie level. + n = kid + + case *LeafNode[V]: + // Collision with an existing path-compressed LeafNode. + // If it's the exact same prefix, simply update the value. + if kid.Prefix == pfx { + kid.Value = val + return true + } + + // Collision resolution: the paths diverge. + // 1. Create a new intermediate node. + // 2. Push the existing leaf down into this new node. + // 3. Replace the current child slot with the new node. + // 4. Descend into the new node to continue inserting 'pfx'. + newNode := new(_NODE_TYPE[V]) + newNode.Insert(kid.Prefix, kid.Value, depth+1) + + n.InsertChild(octet, newNode) + n = newNode + + case *FringeNode[V]: + // Collision with an existing path-compressed FringeNode. + // If the incoming prefix is also a fringe at this depth, update the value. + if IsFringe(depth, pfxLen) { + kid.Value = val + return true + } + + // Collision resolution: + // The existing FringeNode acts as a catch-all (default route) for this sub-trie. + // To allow the incoming prefix to branch further, we expand the FringeNode + // into a full intermediate node and place its value at the default route index (1). + newNode := new(_NODE_TYPE[V]) + newNode.InsertPrefix(1, kid.Value) + + n.InsertChild(octet, newNode) + n = newNode + + default: + panic("logic error, wrong node type") + } + } + panic("unreachable") +} + +// InsertPersist adds or updates a network prefix and its associated value in the trie +// using Copy-On-Write (COW) semantics. Traversal begins at the specified byte depth. +// +// Unlike [Insert], InsertPersist ensures structural integrity of the existing tree +// by cloning internal nodes along the descent path (Copy-On-Write) before mutation. +// +// Parameters: +// - cloneFn: The function used to clone values (V). +// - pfx: The network prefix to insert (must be in canonical/masked form). +// - val: The value to associate with the prefix. +// - depth: The current depth in the trie (0-based byte index). +// +// Returns true if an existing prefix was updated, false if a new insertion occurred. +func (n *_NODE_TYPE[V]) InsertPersist(cloneFn func(V) V, pfx netip.Prefix, val V, depth int) (exists bool) { + ip := pfx.Addr() // the pfx must be in canonical form + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the prefix's octets. Each depth corresponds to an 8-bit stride. + // We descend through the trie until we either reach the final stride (depth == strideCount) + // or find an empty child slot where we can path-compress the remaining strides. + for ; depth < len(octets); depth++ { + octet := octets[depth] + + // The current depth matches the prefix's stride count, meaning this is the final + // node for this prefix. We insert it directly into this node's prefix table. + if depth == strideCount { + return n.InsertPrefix(art.PfxToIdx(octet, modBits), val) + } + + // No child exists at this octet path. Instead of creating intermediate nodes + // for the remaining strides, we path-compress the rest of the prefix into a single child slot. + if !n.Children.Test(octet) { + // If the prefix is perfectly aligned with the next stride boundary (e.g., /16 at depth 1), + // it acts as a default route for everything below it. We store it as a FringeNode. + // Otherwise, it has trailing bits or crosses boundaries, so we store it as a LeafNode. + if IsFringe(depth, pfxLen) { + return n.InsertChild(octet, NewFringeNode(val)) + } + return n.InsertChild(octet, NewLeafNode(pfx, val)) + } + + // A child already exists at this octet path. Retrieve it to either continue + // our descent along the strides or resolve a structural collision with a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *_NODE_TYPE[V]: + // Standard intermediate node: Clone the traversed path to maintain persistence (COW). + // We clone the child node before modifying it, then replace the current child slot. + kid = kid.CloneFlat(cloneFn) + n.InsertChild(octet, kid) + n = kid + + case *LeafNode[V]: + // Collision with an existing path-compressed LeafNode. + // If it's the exact same prefix, simply update the value. + if kid.Prefix == pfx { + kid.Value = val + return true + } + + // Collision resolution: the paths diverge. + // 1. Create a new intermediate node. + // 2. Push the existing leaf down into this new node. + // 3. Replace the current child slot with the new node. + // 4. Descend into the new node to continue inserting 'pfx'. + newNode := new(_NODE_TYPE[V]) + newNode.Insert(kid.Prefix, kid.Value, depth+1) + + n.InsertChild(octet, newNode) + n = newNode + + case *FringeNode[V]: + // Collision with an existing path-compressed FringeNode. + // If the incoming prefix is also a fringe at this depth, update the value. + if IsFringe(depth, pfxLen) { + kid.Value = val + return true + } + + // Collision resolution: + // The existing FringeNode acts as a catch-all (default route) for this sub-trie. + // To allow the incoming prefix to branch further, we expand the FringeNode + // into a full intermediate node and place its value at the default route index (1). + newNode := new(_NODE_TYPE[V]) + newNode.InsertPrefix(1, kid.Value) + + n.InsertChild(octet, newNode) + n = newNode + + default: + panic("logic error, wrong node type") + } + } + panic("unreachable") +} + +// PurgeAndCompress performs bottom-up trie maintenance to restore path compression +// after a deletion. It unwinds the provided stack of parent nodes, identifying +// nodes that have become sparse (i.e., containing only a single prefix or a single +// child node) and prunes them by promoting the underlying entries to the parent level. +// +// This ensures the trie remains memory-efficient by collapsing redundant intermediate +// nodes back into path-compressed LeafNodes or FringeNodes whenever possible. +// +// Parameters: +// - stack: Array of parent nodes to process during bottom-up unwinding. +// - octets: The full path of octets leading to the current node. +// - is4: True for IPv4 processing, false for IPv6. +func (n *_NODE_TYPE[V]) PurgeAndCompress(stack []*_NODE_TYPE[V], octets []uint8, is4 bool) { + // Iterate backwards through the ancestor stack to prune nodes from the bottom up. + for depth := len(stack) - 1; depth >= 0; depth-- { + parent := stack[depth] + octet := octets[depth] + + // Check if the current node is redundant. + // A node may be redundant if it contains exactly one entry (either a prefix or + // a compressed child node). + pfxCount := n.PrefixCount() + childCount := n.ChildCount() + + // If it contains more than one entry, it is always structurally significant and cannot be pruned. + if pfxCount+childCount > 1 { + return + } + + switch { + case childCount == 1: + // The node has exactly one child. We determine if it is a path node, + // a compressed LeafNode, or a compressed FringeNode. + singleAddr, _ := n.Children.FirstSet() + anyKid := n.MustGetChild(singleAddr) + + switch kid := anyKid.(type) { + case *_NODE_TYPE[V]: + // The child is an intermediate path node; the tree structure is required + // at this level. Compression cannot proceed further up. + return + case *LeafNode[V]: + // The child is a compressed LeafNode. Prune the current node + // and re-insert the leaf into the parent to elevate it. + parent.DeleteChild(octet) + parent.Insert(kid.Prefix, kid.Value, depth) + case *FringeNode[V]: + // The child is a compressed FringeNode. Prune the current node + // and re-insert the fringe as a leaf into the parent. + parent.DeleteChild(octet) + + // Reconstruct the full prefix for the fringe, as path compression + // requires the entire CIDR path, not just the remainder. + // depth is the parent's depth, so we offset by 1 for the kid's position. + fringePfx := CidrForFringe(octets, depth+1, is4, singleAddr) + + parent.Insert(fringePfx, kid.Value, depth) + } + + case pfxCount == 1: + // The node has exactly one prefix. Prune the node and elevate the + // prefix to the parent level as a leaf/fringe. + parent.DeleteChild(octet) + + // Retrieve the single prefix stored in this node. + idx, _ := n.Prefixes.FirstSet() + val := n.MustGetPrefix(idx) + + // Reconstruct the prefix from the path for re-insertion. + path := StridePath{} + copy(path[:], octets) + pfx := CidrFromPath(path, depth+1, is4, idx) + + parent.Insert(pfx, val, depth) + default: + panic("unreachable") + } + + // Move up to the next parent in the stack to continue pruning. + n = parent + } +} + +// Delete removes the prefix from the trie rooted at n and returns true if the +// prefix existed, false if it was not found. The prefix must be in canonical +// (masked) form. +// +// The trie uses path compression, so a prefix may be stored in one of three ways: +// - In the current node's prefix table when the prefix length aligns exactly +// with the stride boundary at this depth (depth == strideCount). +// - As a path-compressed FringeNode in a child slot for stride-aligned prefixes +// (e.g. /8, /16, /24); occurs at depth == strideCount-1. +// - As a path-compressed LeafNode in a child slot for prefixes otherwise. +// +// After a successful deletion, PurgeAndCompress walks the ancestor stack to prune +// now-empty nodes and restore path compression upward. +func (n *_NODE_TYPE[V]) Delete(pfx netip.Prefix) (exists bool) { + ip := pfx.Addr() // pfx must be in canonical (masked) form + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Record ancestor nodes as we descend; PurgeAndCompress uses this stack to + // walk back up and clean up empty or re-compressible nodes after deletion. + stack := [MaxTreeDepth]*_NODE_TYPE[V]{} + + for depth, octet := range octets { + depth &= DepthMask // BCE hint; keep Delete on the fast path + + stack[depth] = n // record current node before descending + + // At the stride boundary, the prefix is stored directly in this node's + // prefix table. + if depth == strideCount { + if exists = n.DeletePrefix(art.PfxToIdx(octet, modBits)); !exists { + return false + } + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + } + + // no child node exists at this octet; the prefix is not in the trie + if !n.Children.Test(octet) { + return false + } + + // A child node exists at this octet path, retrieve it. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *_NODE_TYPE[V]: + n = kid // descend to the next trie level + + case *FringeNode[V]: + // A FringeNode holds a single stride-aligned prefix (/8, /16, ...). + // If pfx does not qualify as a fringe at this depth, it cannot be here. + if !IsFringe(depth, pfxLen) { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + case *LeafNode[V]: + // A LeafNode holds exactly one path-compressed prefix. + // Compare using the canonical (masked) form for an exact match. + if kid.Prefix != pfx { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// DeletePersist removes the prefix from the trie rooted at n using Copy-On-Write (COW) semantics. +// It returns true if the prefix existed, false if it was not found. The prefix must be in +// canonical (masked) form. +// +// Like [Delete], this method uses path compression. However, DeletePersist ensures +// the structural integrity of the existing tree by cloning internal nodes along the +// descent path (COW) before mutation. +// +// After a successful deletion, PurgeAndCompress walks the ancestor stack to prune +// now-empty nodes and restore path compression upward. +func (n *_NODE_TYPE[V]) DeletePersist(cloneFn func(V) V, pfx netip.Prefix) (exists bool) { + ip := pfx.Addr() // pfx must be in canonical (masked) form + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Record ancestor nodes as we descend; PurgeAndCompress uses this stack to + // walk back up and clean up empty or re-compressible nodes after deletion. + // Since this is a COW operation, we store the cloned nodes here. + stack := [MaxTreeDepth]*_NODE_TYPE[V]{} + + for depth, octet := range octets { + depth &= DepthMask // BCE hint; keep DeletePersist on the fast path + stack[depth] = n // record current node before descending + + // At the stride boundary, the prefix is stored directly in this node's + // prefix table. + if depth == strideCount { + if exists = n.DeletePrefix(art.PfxToIdx(octet, modBits)); !exists { + return false + } + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + } + + // no child node exists at this octet; the prefix is not in the trie + if !n.Children.Test(octet) { + return false + } + + // A child node exists at this octet path, retrieve it to either continue + // our descent or perform a persistent delete on a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *_NODE_TYPE[V]: + // Standard intermediate node: Clone the traversed path to maintain + // persistence (COW). We clone the child node before modifying it, + // then replace the current child slot. + kid = kid.CloneFlat(cloneFn) + n.InsertChild(octet, kid) + n = kid + continue + + case *FringeNode[V]: + // A FringeNode holds a single stride-aligned prefix (/8, /16, ...). + // If pfx does not qualify as a fringe at this depth, it cannot be here. + if !IsFringe(depth, pfxLen) { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + case *LeafNode[V]: + // A LeafNode holds exactly one path-compressed prefix. + // Compare using the canonical (masked) form for an exact match. + if kid.Prefix != pfx { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// Get retrieves the value associated with the given network prefix. +// Traversal descends through the trie using the prefix's octets. +// +// The lookup handles path compression transparently: +// - If the path matches an internal node at the target stride, the value is retrieved +// from the node's prefix table. +// - If the path leads to a compressed LeafNode or FringeNode, the function verifies +// the prefix match before returning the value. +// +// Parameters: +// - pfx: The network prefix to look up (must be in canonical form). +// +// Returns: +// - val: The value associated with the prefix (zero value if not found). +// - exists: True if the prefix was found, false otherwise. +func (n *_NODE_TYPE[V]) Get(pfx netip.Prefix) (val V, exists bool) { + // The prefix must be provided in canonical (masked) form for correct trie traversal. + ip := pfx.Addr() + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the trie octet by octet based on the prefix path. + for depth, octet := range octets { + // At the target stride boundary, the prefix is expected in this node's + // prefix table. + if depth == strideCount { + return n.GetPrefix(art.PfxToIdx(octet, modBits)) + } + + // If no child exists at this path, the prefix is not in the trie. + kidAny, ok := n.GetChild(octet) + if !ok { + return val, false + } + + // Identify the node type at this path segment. + switch kid := kidAny.(type) { + case *_NODE_TYPE[V]: + // Standard intermediate node: descend to the next level. + n = kid + + case *FringeNode[V]: + // Reached a path-compressed FringeNode. + // Verify if the prefix qualifies as a fringe at this depth to return a match. + if IsFringe(depth, pfxLen) { + return kid.Value, true + } + return val, false + + case *LeafNode[V]: + // Reached a path-compressed LeafNode. + // Check if the stored prefix matches the lookup prefix exactly. + if kid.Prefix == pfx { + return kid.Value, true + } + return val, false + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// Modify performs an in-place modification of a prefix using the provided callback function. +// The callback receives the current value (if found) and existence flag, and returns +// a new value and deletion flag. +// +// Modify returns the size delta (-1, 0, +1). +// This method handles path traversal, node creation for new paths, and automatic +// purge/compress operations after deletions. +// +// Parameters: +// - pfx: The network prefix to modify (must be in canonical form) +// - cb: Callback function that receives (currentValue, exists) and returns (newValue, deleteFlag) +// +// Returns: +// - delta: Size change (-1 for delete, 0 for update/noop, +1 for insert) +func (n *_NODE_TYPE[V]) Modify(pfx netip.Prefix, cb func(val V, found bool) (_ V, del bool)) (delta int) { + var zero V + + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // record the nodes on the path to the deleted node, needed to purge + // and/or path compress nodes after the deletion of a prefix + stack := [MaxTreeDepth]*_NODE_TYPE[V]{} + + // find the proper trie node to update prefix + for depth, octet := range octets { + depth &= DepthMask // BCE + + // push current node on stack for path recording + stack[depth] = n + + // The current depth matches the prefix's stride count, meaning this is the final + // stride for this prefix. Insert or update it directly in this node's prefix table. + if depth == strideCount { + idx := art.PfxToIdx(octet, modBits) + + oldVal, existed := n.GetPrefix(idx) + newVal, del := cb(oldVal, existed) + + // update size if necessary + switch { + case !existed && del: // no-op + return 0 + + case existed && del: // delete + n.DeletePrefix(idx) + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return -1 + + case !existed: // insert + n.InsertPrefix(idx, newVal) + return 1 + + case existed: // update + n.InsertPrefix(idx, newVal) + return 0 + + default: + panic("unreachable") + } + + } + + // go down in tight loop to last octet + if !n.Children.Test(octet) { + // insert prefix path compressed + + newVal, del := cb(zero, false) + if del { + return 0 + } + + // insert + if IsFringe(depth, pfxLen) { + n.InsertChild(octet, NewFringeNode(newVal)) + } else { + n.InsertChild(octet, NewLeafNode(pfx, newVal)) + } + + return 1 + } + + // n.children.Test(octet) == true + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *_NODE_TYPE[V]: + n = kid // descend down to next trie level + continue + + case *LeafNode[V]: + oldVal := kid.Value + + // update existing value if prefixes are equal + if kid.Prefix == pfx { + newVal, del := cb(oldVal, true) + + if !del { + kid.Value = newVal + return 0 + } + + // delete + n.DeleteChild(octet) + + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + + return -1 + } + + // stop if this is a no-op for zero values + newVal, del := cb(zero, false) + if del { + return 0 + } + + // create new node + // insert new child at current leaf position (octet) + newNode := new(_NODE_TYPE[V]) + n.InsertChild(octet, newNode) + + // push the leaf down + // insert pfx with newVal in new node + newNode.Insert(kid.Prefix, kid.Value, depth+1) + newNode.Insert(pfx, newVal, depth+1) + + return 1 + + case *FringeNode[V]: + // update existing value if prefix is fringe + if IsFringe(depth, pfxLen) { + newVal, del := cb(kid.Value, true) + if !del { + kid.Value = newVal + return 0 + } + + // delete + n.DeleteChild(octet) + + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + + return -1 + } + + // stop if this is a no-op for zero values + newVal, del := cb(zero, false) + if del { + return 0 + } + + // create new node + // insert new child at current leaf position (octet) + newNode := new(_NODE_TYPE[V]) + n.InsertChild(octet, newNode) + + // push the fringe down, it becomes a default route (idx=1) + // insert pfx with newVal in new node + newNode.InsertPrefix(1, kid.Value) + newNode.Insert(pfx, newVal, depth+1) + + return 1 + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// EqualRec performs recursive structural equality comparison between two nodes. +// Compares prefix and child bitsets, then recursively compares all stored values +// and child nodes. Returns true if the nodes and their entire subtrees are +// structurally and semantically identical, false otherwise. +// +// The comparison handles different node types (internal nodes, leafNodes, fringeNodes) +// and uses the equal function for value comparisons to support custom equality logic. +func (n *_NODE_TYPE[V]) EqualRec(o *_NODE_TYPE[V]) bool { + if n == nil || o == nil { + return n == o + } + if n == o { + return true + } + + if n.Prefixes.BitSet256 != o.Prefixes.BitSet256 { + return false + } + + if n.Children.BitSet256 != o.Children.BitSet256 { + return false + } + + for idx, nVal := range n.AllIndices() { + oVal := o.MustGetPrefix(idx) // mustGet is ok, bitsets are equal + if !value.Equal(nVal, oVal) { + return false + } + } + + for addr, nKid := range n.AllChildren() { + oKid := o.MustGetChild(addr) // mustGet is ok, bitsets are equal + + switch nKid := nKid.(type) { + case *_NODE_TYPE[V]: + // oKid must also be a node + oKid, ok := oKid.(*_NODE_TYPE[V]) + if !ok { + return false + } + + // compare rec-descent + if !nKid.EqualRec(oKid) { + return false + } + + case *LeafNode[V]: + // oKid must also be a leaf + oKid, ok := oKid.(*LeafNode[V]) + if !ok { + return false + } + + // compare prefixes + if nKid.Prefix != oKid.Prefix { + return false + } + + // compare values + if !value.Equal(nKid.Value, oKid.Value) { + return false + } + + case *FringeNode[V]: + // oKid must also be a fringe + oKid, ok := oKid.(*FringeNode[V]) + if !ok { + return false + } + + // compare values + if !value.Equal(nKid.Value, oKid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// DumpRec recursively descends the trie rooted at n and writes a human-readable +// representation of each visited node to w. +// +// It returns immediately if n is nil or empty. For each visited internal node +// it calls dump to write the node's representation, then iterates its child +// addresses and recurses into children of type *_NODE_TYPE[V] (internal subnodes). +// The path slice and depth together represent the byte-wise path +// from the root to the current node; depth is incremented for each recursion. +// The is4 flag controls IPv4/IPv6 formatting used by dump. +func (n *_NODE_TYPE[V]) DumpRec(w io.Writer, path StridePath, depth int, is4 bool) { + if n == nil || n.IsEmpty() { + return + } + + // dump this node + n.dump(w, path, depth, is4) + + // node may have children, rec-descent down + for addr, child := range n.AllChildren() { + if kid, ok := child.(*_NODE_TYPE[V]); ok { + path[depth] = addr + kid.DumpRec(w, path, depth+1, is4) + } + } +} + +// dump writes a human-readable representation of the node to `w`. +// It prints the node type, depth, formatted path (IPv4 vs IPv6 controlled by `is4`), +// and bit count, followed by any stored prefixes (and their values when applicable), +// the set of child octets, and any path-compressed leaves or fringe entries. +func (n *_NODE_TYPE[V]) dump(w io.Writer, path StridePath, depth int, is4 bool) { + bits := depth * strideLen + indent := strings.Repeat(".", depth) + + // printing values if V is not the empty struct{} + printValues := !value.IsEmptyStruct[V]() + + // node type with depth and octet path and bits. + fmt.Fprintf(w, "\n%s[%s] depth: %d path: [%s] / %d\n", + indent, n.hasType(), depth, ipStridePath(path, depth, is4), bits) + + if nPfxCount := n.PrefixCount(); nPfxCount != 0 { + var buf [256]uint8 + allIndices := n.Prefixes.AsSlice(&buf) + + // print the baseIndices for this node. + fmt.Fprintf(w, "%sindexs(#%d): %v\n", indent, nPfxCount, allIndices) + + // print the prefixes for this node + fmt.Fprintf(w, "%sprefxs(#%d):", indent, nPfxCount) + + for _, idx := range allIndices { + pfx := CidrFromPath(path, depth, is4, idx) + fmt.Fprintf(w, " %s", pfx) + } + + fmt.Fprintln(w) + + // skip printing values if V is zero-sized + if printValues { + + // print the values for this node + fmt.Fprintf(w, "%svalues(#%d):", indent, nPfxCount) + + for _, idx := range allIndices { + val := n.MustGetPrefix(idx) + fmt.Fprintf(w, " %#v", val) + } + + fmt.Fprintln(w) + } + } + + if cc := n.ChildCount(); cc != 0 { + allAddrs := make([]uint8, 0, cc) + childAddrs := make([]uint8, 0, cc) + leafAddrs := make([]uint8, 0, cc) + fringeAddrs := make([]uint8, 0, cc) + + // the node has recursive child nodes or path-compressed leaves + for addr, child := range n.AllChildren() { + allAddrs = append(allAddrs, addr) + + switch child.(type) { + case *_NODE_TYPE[V]: + childAddrs = append(childAddrs, addr) + continue + + case *FringeNode[V]: + fringeAddrs = append(fringeAddrs, addr) + + case *LeafNode[V]: + leafAddrs = append(leafAddrs, addr) + + default: + panic("logic error, wrong node type") + } + } + + // print the children for this node. + fmt.Fprintf(w, "%soctets(#%d): %v\n", indent, len(allAddrs), allAddrs) + + if leafCount := len(leafAddrs); leafCount > 0 { + // print the pathcomp prefixes for this node + fmt.Fprintf(w, "%sleaves(#%d):", indent, leafCount) + + for _, addr := range leafAddrs { + kid := n.MustGetChild(addr).(*LeafNode[V]) + + // skip printing values if V is zero-sized + if printValues { + fmt.Fprintf(w, " %s:{%s, %v}", addrFmt(addr, is4), kid.Prefix, kid.Value) + } else { + fmt.Fprintf(w, " %s:{%s}", addrFmt(addr, is4), kid.Prefix) + } + } + + fmt.Fprintln(w) + } + + if fringeCount := len(fringeAddrs); fringeCount > 0 { + // print the pathcomp prefixes for this node + fmt.Fprintf(w, "%sfringe(#%d):", indent, fringeCount) + + for _, addr := range fringeAddrs { + fringePfx := CidrForFringe(path[:], depth, is4, addr) + + kid := n.MustGetChild(addr).(*FringeNode[V]) + + // skip printing values if V is zero-sized + if printValues { + fmt.Fprintf(w, " %s:{%s, %v}", addrFmt(addr, is4), fringePfx, kid.Value) + } else { + fmt.Fprintf(w, " %s:{%s}", addrFmt(addr, is4), fringePfx) + } + } + + fmt.Fprintln(w) + } + + if childCount := len(childAddrs); childCount > 0 { + // print the next child + fmt.Fprintf(w, "%schilds(#%d):", indent, childCount) + + for _, addr := range childAddrs { + fmt.Fprintf(w, " %s", addrFmt(addr, is4)) + } + + fmt.Fprintln(w) + } + + } +} + +// DumpString traverses the trie to the node at the specified depth along the given +// octet path and returns its string representation via Dump. +// +// If the path is invalid or encounters an unexpected node type during traversal, +// it returns an error message string instead. +// +// Parameters: +// - octets: The path of octets to follow from the root +// - depth: Target depth to reach before dumping (0-based byte index) +// - is4: True for IPv4 formatting, false for IPv6 +// +// Returns a formatted string representation of the target node or an error message. +func (n *_NODE_TYPE[V]) DumpString(octets []uint8, depth int, is4 bool) string { + path := StridePath{} + copy(path[:], octets) + + buf := new(strings.Builder) + for i := range depth { + anyKid, ok := n.GetChild(path[i]) + if !ok { + return fmt.Sprintf("ERROR: kid for %v[%d] is NOT set in node\n", octets, i) + } + + kid, ok := anyKid.(*_NODE_TYPE[V]) + if !ok { + return fmt.Sprintf("ERROR: kid for %v[%d] is NO %s\n", octets, i, "_NODE_TYPE[V]") + } + + // traverse + n = kid + } + + n.dump(buf, path, depth, is4) + return buf.String() +} + +// hasType classifies the given node into one of the nodeType values. +// +// It inspects immediate statistics (prefix count, child count, node, leaf and +// fringe counts) for the node and returns: +// - nullNode: no prefixes and no children +// - stopNode: has children but no subnodes (nodes == 0) +// - halfNode: contains at least one leaf or fringe and also has subnodes, but +// no prefixes +// - fullNode: has prefixes and also has subnodes +// - pathNode: has subnodes only (no prefixes, leaves, or fringes) +// +// The order of these checks is significant to ensure the correct classification. +func (n *_NODE_TYPE[V]) hasType() nodeType { + s := n.Stats() + + // the order is important + switch { + case s.Prefixes == 0 && s.Children == 0: + return nullNode + case s.SubNodes == 0: + return stopNode + case (s.Leaves > 0 || s.Fringes > 0) && s.SubNodes > 0 && s.Prefixes == 0: + return halfNode + case (s.Prefixes > 0 || s.Leaves > 0 || s.Fringes > 0) && s.SubNodes > 0: + return fullNode + case (s.Prefixes == 0 && s.Leaves == 0 && s.Fringes == 0) && s.SubNodes > 0: + return pathNode + default: + panic(fmt.Sprintf("UNREACHABLE: pfx: %d, chld: %d, node: %d, leaf: %d, fringe: %d", + s.Prefixes, s.Children, s.SubNodes, s.Leaves, s.Fringes)) + } +} + +// Stats returns immediate statistics for n: counts of prefixes and children, +// and a classification of each child into nodes, leaves, or fringes. +// It inspects only the direct children of n (not the whole subtree). +// Panics if a child has an unexpected concrete type. +func (n *_NODE_TYPE[V]) Stats() (s StatsT) { + s.Prefixes = n.PrefixCount() + s.Children = n.ChildCount() + + for _, child := range n.AllChildren() { + switch child.(type) { + case *_NODE_TYPE[V]: + s.SubNodes++ + + case *FringeNode[V]: + s.Fringes++ + + case *LeafNode[V]: + s.Leaves++ + + default: + panic("logic error, wrong node type") + } + } + + return s +} + +// StatsRec returns aggregated statistics for the subtree rooted at n. +// +// It walks the node tree recursively and sums immediate counts (prefixes and +// child slots) plus the number of nodes, leaves, and fringe nodes in the +// subtree. If n is nil or empty, a zeroed stats is returned. The returned +// SubNodes count includes the current node. The function will panic if a child +// has an unexpected concrete type. +func (n *_NODE_TYPE[V]) StatsRec() (s StatsT) { + if n == nil || n.IsEmpty() { + return s + } + + s.Prefixes = n.PrefixCount() + s.Children = n.ChildCount() + s.SubNodes = 1 // this node + s.Leaves = 0 + s.Fringes = 0 + + for _, child := range n.AllChildren() { + switch kid := child.(type) { + case *_NODE_TYPE[V]: + // rec-descent + rs := kid.StatsRec() + + s.Prefixes += rs.Prefixes + s.Children += rs.Children + s.SubNodes += rs.SubNodes + s.Leaves += rs.Leaves + s.Fringes += rs.Fringes + + case *FringeNode[V]: + s.Fringes++ + + case *LeafNode[V]: + s.Leaves++ + + default: + panic("logic error, wrong node type") + } + } + + return s +} + +// FprintRec recursively prints a hierarchical CIDR tree representation +// starting from this node to the provided writer. The output shows the +// routing table structure in human-readable format for debugging and analysis. +func (n *_NODE_TYPE[V]) FprintRec(w io.Writer, parent TrieItem[V], pad string) error { + // recursion stop condition + if n == nil || n.IsEmpty() { + return nil + } + + // get direct covered childs for this parent ... + directItems := n.DirectItemsRec(parent.Idx, parent.Path, parent.Depth, parent.Is4) + + // sort them by netip.Prefix, not by baseIndex + slices.SortFunc(directItems, func(a, b TrieItem[V]) int { + return CmpPrefix(a.Cidr, b.Cidr) + }) + + // printing values if V is not the empty struct{} + printValues := !value.IsEmptyStruct[V]() + + // for all direct item under this node ... + for i, item := range directItems { + // symbols used in tree + glyph := "├─ " + space := "│ " + + // ... treat last kid special + if i == len(directItems)-1 { + glyph = "└─ " + space = " " + } + + var err error + // val is the empty struct, don't print it + if printValues { + _, err = fmt.Fprintf(w, "%s%s (%v)\n", pad+glyph, item.Cidr, item.Val) + } else { + // skip printing values if V is zero-sized + _, err = fmt.Fprintf(w, "%s%s\n", pad+glyph, item.Cidr) + } + + if err != nil { + return err + } + + // rec-descent with this item as parent + nextNode, _ := item.Node.(*_NODE_TYPE[V]) + if err = nextNode.FprintRec(w, item, pad+space); err != nil { + return err + } + } + + return nil +} + +// DirectItemsRec, returns the direct covered items by parent. +// It's a complex recursive function, you have to know the data structure +// by heart to understand this function! +func (n *_NODE_TYPE[V]) DirectItemsRec(parentIdx uint8, path StridePath, depth int, is4 bool) (directItems []TrieItem[V]) { + // recursion stop condition + if n == nil || n.IsEmpty() { + return nil + } + + // prefixes: + // for all idx's (prefixes mapped by baseIndex) in this node + // do a longest-prefix-match + for idx, val := range n.AllIndices() { + // tricky part, skip self + // test with next possible lpm (idx>>1), it's a complete binary tree + nextIdx := idx >> 1 + + // fast skip, lpm not possible + if nextIdx < parentIdx { + continue + } + + // do a longest-prefix-match + lpm, _, _ := n.LookupIdx(nextIdx) + + // be aware, 0 is here a possible value for parentIdx and lpm (if not found) + if lpm == parentIdx { + // prefix is directly covered by parent + + item := TrieItem[V]{ + Node: n, + Is4: is4, + Path: path, + Depth: depth, + Idx: idx, + // get the prefix back from trie + Cidr: CidrFromPath(path, depth, is4, idx), + Val: val, + } + + directItems = append(directItems, item) + } + } + + // children: + for addr, child := range n.AllChildren() { + hostIdx := art.OctetToIdx(addr) + + // do a longest-prefix-match + lpm, _, _ := n.LookupIdx(hostIdx) + + // be aware, 0 is here a possible value for parentIdx and lpm (if not found) + if lpm == parentIdx { + // child is directly covered by parent + switch kid := child.(type) { + case *_NODE_TYPE[V]: // traverse rec-descent, call with next child node, + // next trie level, set parentIdx to 0, adjust path and depth + path[depth] = addr + directItems = append(directItems, kid.DirectItemsRec(0, path, depth+1, is4)...) + + case *LeafNode[V]: // path-compressed child, stops recursion for this child + item := TrieItem[V]{ + Node: nil, + Is4: is4, + Cidr: kid.Prefix, + Val: kid.Value, + } + directItems = append(directItems, item) + + case *FringeNode[V]: // path-compressed fringe, stops recursion for this child + item := TrieItem[V]{ + Node: nil, + Is4: is4, + // get the prefix back from trie + Cidr: CidrForFringe(path[:], depth, is4, addr), + Val: kid.Value, + } + directItems = append(directItems, item) + + default: + panic("logic error, wrong node type") + } + } + } + + return directItems +} + +// UnionRec recursively merges another node o into the receiver node n. +// +// All prefix and child entries from o are cloned and inserted into n. +// If a prefix already exists in n, its value is overwritten by the value from o, +// and the duplicate is counted in the return value. This count can later be used +// to update size-related metadata in the parent trie. +// +// The union handles all possible combinations of child node types (node, leaf, fringe) +// between the two nodes. Structural conflicts are resolved by creating new intermediate +// *_NODE_TYPE[V] objects and pushing both children further down the trie. Leaves and fringes +// are also recursively relocated as needed to preserve prefix semantics. +// +// The merge operation is destructive on the receiver n, but leaves the source node o unchanged. +// +// Returns the number of duplicate prefixes that were overwritten during merging. +func (n *_NODE_TYPE[V]) UnionRec(cloneFn func(V) V, o *_NODE_TYPE[V], depth int) (duplicates int) { + if cloneFn == nil { + cloneFn = func(v V) V { return v } + } + + buf := [256]uint8{} + + // for all prefixes in other node do ... + for _, oIdx := range o.Prefixes.AsSlice(&buf) { + // clone/copy the value from other node at idx + val := o.MustGetPrefix(oIdx) + clonedVal := cloneFn(val) + + // insert/overwrite cloned value from o into n + if n.InsertPrefix(oIdx, clonedVal) { + // this prefix is duplicate in n and o + duplicates++ + } + } + + // for all child addrs in other node do ... + for _, addr := range o.Children.AsSlice(&buf) { + otherChild := o.MustGetChild(addr) + thisChild, thisExists := n.GetChild(addr) + + // Use helper function to handle all 4x3 combinations + duplicates += n.handleMatrix(cloneFn, thisExists, thisChild, otherChild, addr, depth) + } + + return duplicates +} + +// UnionRecPersist is similar to unionRec but performs an immutable union of nodes. +func (n *_NODE_TYPE[V]) UnionRecPersist(cloneFn func(V) V, o *_NODE_TYPE[V], depth int) (duplicates int) { + if cloneFn == nil { + cloneFn = func(v V) V { return v } + } + + buf := [256]uint8{} + + // for all prefixes in other node do ... + for _, oIdx := range o.Prefixes.AsSlice(&buf) { + // clone/copy the value from other node + val := o.MustGetPrefix(oIdx) + clonedVal := cloneFn(val) + + // insert/overwrite cloned value from o into n + if exists := n.InsertPrefix(oIdx, clonedVal); exists { + // this prefix is duplicate in n and o + duplicates++ + } + } + + // for all child addrs in other node do ... + for _, addr := range o.Children.AsSlice(&buf) { + otherChild := o.MustGetChild(addr) + thisChild, thisExists := n.GetChild(addr) + + // Use helper function to handle all 4x3 combinations + duplicates += n.handleMatrixPersist(cloneFn, thisExists, thisChild, otherChild, addr, depth) + } + + return duplicates +} + +// handleMatrix, 12 possible combinations to union this child and other child +// +// THIS, OTHER: (always clone the other kid!) +// -------------- +// NULL, node <-- insert node at addr +// NULL, leaf <-- insert leaf at addr +// NULL, fringe <-- insert fringe at addr +// +// node, node <-- union rec-descent with node +// node, leaf <-- insert leaf at depth+1 +// node, fringe <-- insert fringe at depth+1 +// +// leaf, node <-- insert new node, push this leaf down, union rec-descent +// leaf, leaf <-- insert new node, push both leaves down (!first check equality) +// leaf, fringe <-- insert new node, push this leaf and fringe down +// +// fringe, node <-- insert new node, push this fringe down, union rec-descent +// fringe, leaf <-- insert new node, push this fringe down, insert other leaf at depth+1 +// fringe, fringe <-- just overwrite value +func (n *_NODE_TYPE[V]) handleMatrix(cloneFn func(V) V, thisExists bool, thisChild, otherChild any, addr uint8, depth int) int { + // Do ALL type assertions upfront - reduces line noise + var ( + thisNode, thisIsNode = thisChild.(*_NODE_TYPE[V]) + thisLeaf, thisIsLeaf = thisChild.(*LeafNode[V]) + thisFringe, thisIsFringe = thisChild.(*FringeNode[V]) + + otherNode, otherIsNode = otherChild.(*_NODE_TYPE[V]) + otherLeaf, otherIsLeaf = otherChild.(*LeafNode[V]) + otherFringe, otherIsFringe = otherChild.(*FringeNode[V]) + ) + + // just insert cloned child at this empty slot + if !thisExists { + switch { + case otherIsNode: + n.InsertChild(addr, otherNode.CloneRec(cloneFn)) + case otherIsLeaf: + n.InsertChild(addr, &LeafNode[V]{Prefix: otherLeaf.Prefix, Value: cloneFn(otherLeaf.Value)}) + case otherIsFringe: + n.InsertChild(addr, &FringeNode[V]{Value: cloneFn(otherFringe.Value)}) + default: + panic("logic error, wrong node type") + } + return 0 + } + + // Case 1: Special cases that DON'T need a new node + + // Special case: fringe + fringe -> just overwrite value + if thisIsFringe && otherIsFringe { + thisFringe.Value = cloneFn(otherFringe.Value) + return 1 + } + + // Special case: leaf + leaf with same prefix -> just overwrite value + if thisIsLeaf && otherIsLeaf && thisLeaf.Prefix == otherLeaf.Prefix { + thisLeaf.Value = cloneFn(otherLeaf.Value) + return 1 + } + + // Case 2: thisChild is already a node - insert into it, no new node needed + if thisIsNode { + switch { + case otherIsNode: + return thisNode.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if thisNode.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if thisNode.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong node type") + } + } + + // Case 3: All remaining cases need a new node + // (thisChild is leaf or fringe, and we didn't hit the special cases above) + + nc := new(_NODE_TYPE[V]) + + // Push existing child down into new node + switch { + case thisIsLeaf: + nc.Insert(thisLeaf.Prefix, thisLeaf.Value, depth+1) + case thisIsFringe: + nc.InsertPrefix(1, thisFringe.Value) + default: + panic("logic error, unexpected this child type") + } + + // Replace child with new node + n.InsertChild(addr, nc) + + // Now handle other child + switch { + case otherIsNode: + return nc.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if nc.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if nc.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong other node type") + } +} + +// handleMatrixPersist, 12 possible combinations to union this child and other child +// +// THIS, OTHER: (always clone the other kid!) +// -------------- +// NULL, node <-- insert node at addr +// NULL, leaf <-- insert leaf at addr +// NULL, fringe <-- insert fringe at addr +// +// node, node <-- union rec-descent with node +// node, leaf <-- insert leaf at depth+1 +// node, fringe <-- insert fringe at depth+1 +// +// leaf, node <-- insert new node, push this leaf down, union rec-descent +// leaf, leaf <-- insert new node, push both leaves down (!first check equality) +// leaf, fringe <-- insert new node, push this leaf and fringe down +// +// fringe, node <-- insert new node, push this fringe down, union rec-descent +// fringe, leaf <-- insert new node, push this fringe down, insert other leaf at depth+1 +// fringe, fringe <-- just overwrite value +func (n *_NODE_TYPE[V]) handleMatrixPersist(cloneFn func(V) V, thisExists bool, thisChild, otherChild any, addr uint8, depth int) int { + // Do ALL type assertions upfront - reduces line noise + var ( + thisNode, thisIsNode = thisChild.(*_NODE_TYPE[V]) + thisLeaf, thisIsLeaf = thisChild.(*LeafNode[V]) + thisFringe, thisIsFringe = thisChild.(*FringeNode[V]) + + otherNode, otherIsNode = otherChild.(*_NODE_TYPE[V]) + otherLeaf, otherIsLeaf = otherChild.(*LeafNode[V]) + otherFringe, otherIsFringe = otherChild.(*FringeNode[V]) + ) + + // just insert cloned child at this empty slot + if !thisExists { + switch { + case otherIsNode: + n.InsertChild(addr, otherNode.CloneRec(cloneFn)) + case otherIsLeaf: + n.InsertChild(addr, &LeafNode[V]{Prefix: otherLeaf.Prefix, Value: cloneFn(otherLeaf.Value)}) + case otherIsFringe: + n.InsertChild(addr, &FringeNode[V]{Value: cloneFn(otherFringe.Value)}) + default: + panic("logic error, wrong node type") + } + return 0 + } + + // Case 1: Special cases that DON'T need a new node + + // Special case: fringe + fringe -> just overwrite value + if thisIsFringe && otherIsFringe { + thisFringe.Value = cloneFn(otherFringe.Value) + return 1 + } + + // Special case: leaf + leaf with same prefix -> just overwrite value + if thisIsLeaf && otherIsLeaf && thisLeaf.Prefix == otherLeaf.Prefix { + thisLeaf.Value = cloneFn(otherLeaf.Value) + return 1 + } + + // Case 2: thisChild is already a node - clone this node, insert into it + if thisIsNode { + // CLONE the node + + // thisNode points now to cloned kid + thisNode = thisNode.CloneFlat(cloneFn) + + // replace kid with cloned thisKid + n.InsertChild(addr, thisNode) + + switch { + case otherIsNode: + return thisNode.UnionRecPersist(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if thisNode.InsertPersist(cloneFn, otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if thisNode.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong node type") + } + } + + // Case 3: All remaining cases need a new node + // (thisChild is leaf or fringe, and we didn't hit the special cases above) + + nc := new(_NODE_TYPE[V]) + + // Push existing child down into new node + switch { + case thisIsLeaf: + nc.Insert(thisLeaf.Prefix, thisLeaf.Value, depth+1) + case thisIsFringe: + nc.InsertPrefix(1, thisFringe.Value) + default: + panic("logic error, unexpected this child type") + } + + // Replace child with new node + n.InsertChild(addr, nc) + + // Now handle other child + switch { + case otherIsNode: + return nc.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if nc.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if nc.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong other node type") + } +} + +// AllRec recursively traverses the trie starting at the current node, +// applying the provided yield function to every stored prefix and value. +// +// For each route entry (prefix and value), yield is invoked. If yield returns false, +// the traversal stops immediately, and false is propagated upwards, +// enabling early termination. +// +// The function handles all prefix entries in the current node, as well as any children - +// including sub-nodes, leaf nodes with full prefixes, and fringe nodes +// representing path-compressed prefixes. IP prefix reconstruction is performed on-the-fly +// from the current path and depth. +// +// The traversal order is not defined. This implementation favors simplicity +// and runtime efficiency over consistency of iteration sequence. +func (n *_NODE_TYPE[V]) AllRec(path StridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { + var buf [256]uint8 + for _, idx := range n.Prefixes.AsSlice(&buf) { + cidr := CidrFromPath(path, depth, is4, idx) + val := n.MustGetPrefix(idx) + + // callback for this prefix and val + if !yield(cidr, val) { + // early exit + return false + } + } + + // for all children (nodes and leaves) in this node do ... + for _, addr := range n.Children.AsSlice(&buf) { + anyKid := n.MustGetChild(addr) + switch kid := anyKid.(type) { + case *_NODE_TYPE[V]: + // rec-descent with this node + path[depth] = addr + if !kid.AllRec(path, depth+1, is4, yield) { + // early exit + return false + } + case *LeafNode[V]: + // callback for this leaf + if !yield(kid.Prefix, kid.Value) { + // early exit + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// AllRecSorted recursively traverses the trie in prefix-sorted order and applies +// the given yield function to each stored prefix and value. +// +// Unlike AllRec, this implementation ensures that route entries are visited in +// canonical prefix sort order. To achieve this, +// both the prefixes and children of the current node are gathered, sorted, +// and then interleaved during traversal based on logical octet positioning. +// +// The function first sorts relevant entries by their prefix index and address value, +// using a comparison function that ranks prefixes according to their mask length and position. +// Then it walks the trie, always yielding child entries that fall before the current prefix, +// followed by the prefix itself. Remaining children are processed once all prefixes have been visited. +// +// Prefixes are reconstructed on-the-fly from the traversal path, and iteration includes all child types: +// inner nodes (recursive descent), leaf nodes, and fringe (compressed) prefixes. +// +// The order is stable and predictable, making the function suitable for use cases +// like table exports, comparisons or serialization. +// +// Parameters: +// - path: the current traversal path through the trie +// - depth: current depth in the trie (0-based) +// - is4: true for IPv4 processing, false for IPv6 +// - yield: callback function invoked for each prefix/value pair +// +// Returns false if yield function requests early termination. +func (n *_NODE_TYPE[V]) AllRecSorted(path StridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { + // get slice of all child octets, sorted by addr + var childBuf [256]uint8 + allChildAddrs := n.Children.AsSlice(&childBuf) + + // get slice of all indexes, sorted by idx + var idxBuf [256]uint8 + allIndices := n.Prefixes.AsSlice(&idxBuf) + + // sort indices in CIDR sort order + slices.SortFunc(allIndices, CmpIndexRank) + + childCursor := 0 + + // yield indices and children in CIDR sort order + for _, pfxIdx := range allIndices { + pfxOctet, _ := art.IdxToPfx(pfxIdx) + + // yield all children before idx + for j := childCursor; j < len(allChildAddrs); j++ { + childAddr := allChildAddrs[j] + + if childAddr >= pfxOctet { + break + } + + // yield the node (rec-descent) or leaf + anyKid := n.MustGetChild(childAddr) + switch kid := anyKid.(type) { + case *_NODE_TYPE[V]: + path[depth] = childAddr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, childAddr) + if !yield(fringePfx, kid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + + childCursor++ + } + + // yield the prefix for this idx + cidr := CidrFromPath(path, depth, is4, pfxIdx) + // n.prefixes.Items[i] not possible after sorting allIndices + if !yield(cidr, n.MustGetPrefix(pfxIdx)) { + return false + } + } + + // yield the rest of leaves and nodes (rec-descent) + for j := childCursor; j < len(allChildAddrs); j++ { + addr := allChildAddrs[j] + anyKid := n.MustGetChild(addr) + switch kid := anyKid.(type) { + case *_NODE_TYPE[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + if !yield(fringePfx, kid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// EachLookupPrefix performs a hierarchical lookup of all matching prefixes +// in the current node’s 8-bit stride-based prefix table. +// +// The function walks up the trie-internal complete binary tree (CBT), +// testing each possible prefix length mask (in decreasing order of specificity), +// and invokes the yield function for every matching entry. +// +// The given idx refers to the position for this stride's prefix and is used +// to derive a backtracking path through the CBT by repeatedly halving the index. +// At each step, if a prefix exists in the table, its corresponding CIDR is +// reconstructed and yielded. If yield returns false, traversal stops early. +// +// This function is intended for internal use during supernet traversal and +// does not descend the trie further. +func (n *_NODE_TYPE[V]) EachLookupPrefix(ip netip.Addr, depth int, pfxIdx uint8, yield func(netip.Prefix, V) bool) (ok bool) { + for ; pfxIdx > 0; pfxIdx >>= 1 { + if n.Prefixes.Test(pfxIdx) { + val := n.MustGetPrefix(pfxIdx) + + // get the CIDR back + _, pfxLen := art.IdxToPfx(pfxIdx) + cidr, _ := ip.Prefix(depth<<3 + int(pfxLen)) + + if !yield(cidr, val) { + return false + } + } + } + + return true +} + +// EachSubnet yields all prefix entries and child nodes covered by a given parent prefix, +// sorted in natural CIDR order, within the current node. +// +// The function iterates through all prefixes and children from the node’s stride tables. +// Only entries that fall within the address range defined by the parent prefix index (pfxIdx) +// are included. Matching entries are buffered, sorted, and passed through to the yield function. +// +// Child entries (nodes, leaves, fringes) that fall under the covered address range +// are processed recursively via AllRecSorted to ensure sorted traversal. +// +// This function is intended for internal use by Subnets(), and it assumes the +// current node is positioned at the point in the trie corresponding to the parent prefix. +func (n *_NODE_TYPE[V]) EachSubnet(octets []byte, depth int, is4 bool, pfxIdx uint8, yield func(netip.Prefix, V) bool) bool { + // octets as array, needed below more than once + var path StridePath + copy(path[:], octets) + + pfxFirstAddr, pfxLastAddr := art.IdxToRange(pfxIdx) + + allCoveredIndices := make([]uint8, 0, n.PrefixCount()) + + var buf [256]uint8 + for _, idx := range n.Prefixes.AsSlice(&buf) { + thisFirstAddr, thisLastAddr := art.IdxToRange(idx) + + if thisFirstAddr >= pfxFirstAddr && thisLastAddr <= pfxLastAddr { + allCoveredIndices = append(allCoveredIndices, idx) + } + } + + // sort indices in CIDR sort order + slices.SortFunc(allCoveredIndices, CmpIndexRank) + + // 2. collect all covered child addrs by prefix + + allCoveredChildAddrs := make([]uint8, 0, n.ChildCount()) + for _, addr := range n.Children.AsSlice(&buf) { + if addr >= pfxFirstAddr && addr <= pfxLastAddr { + allCoveredChildAddrs = append(allCoveredChildAddrs, addr) + } + } + + // 3. yield covered indices, path-compressed prefixes + // and children in CIDR sort order + + addrCursor := 0 + + // yield indices and children in CIDR sort order + for _, pfxIdx := range allCoveredIndices { + pfxOctet, _ := art.IdxToPfx(pfxIdx) + + // yield all children before idx + for j := addrCursor; j < len(allCoveredChildAddrs); j++ { + addr := allCoveredChildAddrs[j] + if addr >= pfxOctet { + break + } + + // yield the node or leaf? + switch kid := n.MustGetChild(addr).(type) { + case *_NODE_TYPE[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + + addrCursor++ + } + + // yield the prefix for this idx + cidr := CidrFromPath(path, depth, is4, pfxIdx) + // n.prefixes.Items[i] not possible after sorting allIndices + if !yield(cidr, n.MustGetPrefix(pfxIdx)) { + return false + } + } + + // yield the rest of leaves and nodes (rec-descent) + for _, addr := range allCoveredChildAddrs[addrCursor:] { + // yield the node or leaf? + switch kid := n.MustGetChild(addr).(type) { + case *_NODE_TYPE[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// Supernets yields all supernet prefixes of pfx that exist in the trie, +// in reverse order (most-specific first, least-specific last). +// +// It traverses upward from the given prefix toward the root, collecting +// matching prefixes along the path. The traversal uses a stack to yield +// results in reverse order, so that more-specific supernets appear before +// less-specific ones. +// +// The function handles all node types (internal nodes, leaves, and fringes) +// and stops early if the yield callback returns false. +// +// Parameters: +// - pfx: The prefix for which to find supernets +// - yield: Callback function invoked for each supernet prefix/value pair +// +// The yield function receives prefix/value pairs and returns false to stop +// the iteration early. +func (n *_NODE_TYPE[V]) Supernets(pfx netip.Prefix, yield func(netip.Prefix, V) bool) { + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // stack of the traversed nodes for reverse ordering of supernets + stack := [MaxTreeDepth]*_NODE_TYPE[V]{} + + // run variable, used after for loop + var depth int + var octet byte + + // find last node along this octet path +LOOP: + for depth, octet = range octets { + // stepped one past the last stride of interest; back up to last and exit + if depth > strideCount { + depth-- + break + } + // push current node on stack + stack[depth] = n + + // descend down the trie + if !n.Children.Test(octet) { + break LOOP + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *_NODE_TYPE[V]: + n = kid + continue LOOP // descend down to next trie level + + case *LeafNode[V]: + if kid.Prefix.Bits() > pfx.Bits() { + break LOOP + } + + if kid.Prefix.Overlaps(pfx) { + if !yield(kid.Prefix, kid.Value) { + // early exit + return + } + } + // end of trie along this octets path + break LOOP + + case *FringeNode[V]: + fringePfx := CidrForFringe(octets, depth, is4, octet) + if fringePfx.Bits() > pfx.Bits() { + break LOOP + } + + if fringePfx.Overlaps(pfx) { + if !yield(fringePfx, kid.Value) { + // early exit + return + } + } + // end of trie along this octets path + break LOOP + + default: + panic("logic error, wrong node type") + } + } + + // start backtracking, unwind the stack + for ; depth >= 0; depth-- { + n = stack[depth] + + // only the lastOctet may have a different prefix len + // all others are just host routes + var idx uint8 + octet = octets[depth] + // Last “octet” from prefix + // Note: For /32 and /128, depth never reaches strideCount (4/16), + if depth == strideCount { + idx = art.PfxToIdx(octet, modBits) + } else { + idx = art.OctetToIdx(octet) + } + + // micro benchmarking, skip if there is no match + if !n.Contains(idx) { + continue + } + + // yield all the matching prefixes, not just the lpm + if !n.EachLookupPrefix(ip, depth, idx, yield) { + // early exit + return + } + } +} + +// Subnets yields all subnet prefixes covered by pfx that exist in the trie, +// in CIDR sort order. +// +// It first locates the trie node corresponding to pfx, then recursively +// yields all prefixes and child entries contained within that subtree. +// The traversal uses sorted iteration to maintain canonical CIDR ordering. +// +// The function handles various node types (internal nodes, leaves, and fringes) +// and uses EachSubnet and AllRecSorted for sorted traversal of covered prefixes. +// +// Parameters: +// - pfx: The parent prefix whose subnets should be yielded +// - yield: Callback function invoked for each subnet prefix/value pair +// +// The yield function receives prefix/value pairs and returns false to stop +// the iteration early. If pfx doesn't exist in the trie, no prefixes are yielded. +func (n *_NODE_TYPE[V]) Subnets(pfx netip.Prefix, yield func(netip.Prefix, V) bool) { + // values derived from pfx + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // find the trie node + for depth, octet := range octets { + // Last “octet” from prefix + // Note: For /32 and /128, depth never reaches strideCount (4/16), + // so those are handled below via the fringe/leaf path. + if depth == strideCount { + idx := art.PfxToIdx(octet, modBits) + n.EachSubnet(octets, depth, is4, idx, yield) + return + } + + if !n.Children.Test(octet) { + return + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *_NODE_TYPE[V]: + n = kid + continue // descend down to next trie level + + case *LeafNode[V]: + if pfx.Bits() <= kid.Prefix.Bits() && pfx.Overlaps(kid.Prefix) { + yield(kid.Prefix, kid.Value) + } + return // immediate return + + case *FringeNode[V]: + // get the LPM prefix back from ip and depth + // it's a fringe, bits are always /8, /16, /24, ... + fringePfx, _ := ip.Prefix((depth + 1) << 3) + + if pfx.Bits() <= fringePfx.Bits() && pfx.Overlaps(fringePfx) { + yield(fringePfx, kid.Value) + } + return // immediate return + + default: + panic("logic error, wrong node type") + } + } +} + +// Overlaps recursively compares two trie nodes and returns true +// if any of their prefixes or descendants overlap. +// +// The implementation checks for: +// 1. Direct overlapping prefixes on this node level +// 2. Prefixes in one node overlapping with children in the other +// 3. Matching child addresses in both nodes, which are recursively compared +// +// All 12 possible type combinations for child entries (node, leaf, fringe) are supported. +// +// The function is optimized for early exit on first match and uses heuristics to +// choose between set-based and loop-based matching for performance. +func (n *_NODE_TYPE[V]) Overlaps(o *_NODE_TYPE[V], depth int) bool { + nPfxCount := n.PrefixCount() + oPfxCount := o.PrefixCount() + + nChildCount := n.ChildCount() + oChildCount := o.ChildCount() + + // ############################## + // 1. Test if any routes overlaps + // ############################## + + // full cross check + if nPfxCount > 0 && oPfxCount > 0 { + if n.OverlapsRoutes(o) { + return true + } + } + + // #################################### + // 2. Test if routes overlaps any child + // #################################### + + // swap nodes to help chance on its way, + // if the first call to expensive overlapsChildrenIn() is already true, + // if both orders are false it doesn't help either + if nChildCount > oChildCount { + n, o = o, n + + nPfxCount = n.PrefixCount() + oPfxCount = o.PrefixCount() + + nChildCount = n.ChildCount() + oChildCount = o.ChildCount() + } + + if nPfxCount > 0 && oChildCount > 0 { + if n.OverlapsChildrenIn(o) { + return true + } + } + + // symmetric reverse + if oPfxCount > 0 && nChildCount > 0 { + if o.OverlapsChildrenIn(n) { + return true + } + } + + // ############################################ + // 3. children with same octet in nodes n and o + // ############################################ + + // stop condition, n or o have no children + if nChildCount == 0 || oChildCount == 0 { + return false + } + + // stop condition, no child with identical octet in n and o + if !n.Children.Intersects(&o.Children.BitSet256) { + return false + } + + return n.OverlapsSameChildren(o, depth) +} + +// OverlapsRoutes compares the prefix sets of two nodes (n and o). +// +// It first checks for direct bitset intersection (identical indices), +// then walks both prefix sets using the Contains method to detect if any +// of the n-prefixes is contained in o, or vice versa. +func (n *_NODE_TYPE[V]) OverlapsRoutes(o *_NODE_TYPE[V]) bool { + // some prefixes are identical, trivial overlap + if n.Prefixes.Intersects(&o.Prefixes.BitSet256) { + return true + } + + // get the lowest idx (biggest prefix) + nFirstIdx, _ := n.Prefixes.FirstSet() + oFirstIdx, _ := o.Prefixes.FirstSet() + + // start with other min value + nIdx := oFirstIdx + oIdx := nFirstIdx + + nOK := true + oOK := true + + // zip, range over n and o together to help chance on its way + for nOK || oOK { + if nOK { + // does any route in o overlap this prefix from n + if nIdx, nOK = n.Prefixes.NextSet(nIdx); nOK { + if o.Contains(nIdx) { + return true + } + + if nIdx == 255 { + // stop, don't overflow uint8! + nOK = false + } else { + nIdx++ + } + } + } + + if oOK { + // does any route in n overlap this prefix from o + if oIdx, oOK = o.Prefixes.NextSet(oIdx); oOK { + if n.Contains(oIdx) { + return true + } + + if oIdx == 255 { + // stop, don't overflow uint8! + oOK = false + } else { + oIdx++ + } + } + } + } + + return false +} + +// OverlapsChildrenIn checks whether the prefixes in node n +// overlap with any children (by address range) in node o. +// +// Uses bitset intersection or manual iteration heuristically, +// depending on prefix and child count. +// +// Bitset-based matching uses precomputed coverage tables +// to avoid per-address looping. This is critical for high fan-out nodes. +func (n *_NODE_TYPE[V]) OverlapsChildrenIn(o *_NODE_TYPE[V]) bool { + pfxCount := n.PrefixCount() + childCount := o.ChildCount() + + // heuristic: 15 is the crossover point where bitset operations become + // more efficient than iteration, determined by micro benchmarks on typical + // routing table distributions + const overlapsRangeCutoff = 15 + + doRange := childCount < overlapsRangeCutoff || pfxCount > overlapsRangeCutoff + + // do range over, not so many children and maybe too many prefixes for other algo below + var buf [256]uint8 + if doRange { + for _, addr := range o.Children.AsSlice(&buf) { + if n.Contains(art.OctetToIdx(addr)) { + return true + } + } + return false + } + + // do bitset intersection, alloted route table with child octets + // maybe too many children for range-over or not so many prefixes to + // build the alloted routing table from them + + // use allot table with prefixes as bitsets, bitsets are precalculated. + for _, idx := range n.Prefixes.AsSlice(&buf) { + if o.Children.Intersects(&allot.FringeRoutesLookupTbl[idx]) { + return true + } + } + + return false +} + +// OverlapsSameChildren compares all matching child addresses (octets) +// between node n and node o recursively. +// +// For each shared address, the corresponding child nodes (of any type) +// are compared using _NODE_TYPEOverlapsTwoChildren, which handles all +// node/leaf/fringe combinations. +func (n *_NODE_TYPE[V]) OverlapsSameChildren(o *_NODE_TYPE[V], depth int) bool { + // intersect the child bitsets from n with o + commonChildren := n.Children.Intersection(&o.Children.BitSet256) + + for addr, ok := commonChildren.NextSet(0); ok; { + nChild := n.MustGetChild(addr) + oChild := o.MustGetChild(addr) + + if n.OverlapsTwoChildren(nChild, oChild, depth+1) { + return true + } + + if addr == 255 { + break // Prevent uint8 overflow + } + + addr, ok = commonChildren.NextSet(addr + 1) + } + return false +} + +// OverlapsPrefixAtDepth returns true if any route in the subtree rooted at this node +// overlaps with the given pfx, starting the comparison at the specified depth. +// +// This function supports structural overlap detection even in compressed or sparse +// paths within the trie, including fringe and leaf nodes. Matching is directional: +// it returns true if a route fully covers pfx, or if pfx covers an existing route. +// +// At each step, it checks for visible prefixes and children that may intersect the +// target prefix via stride-based longest-prefix test. The walk terminates early as +// soon as a structural overlap is found. +// +// This function underlies the top-level OverlapsPrefix behavior and handles details of +// trie traversal across varying prefix lengths and compression levels. +func (n *_NODE_TYPE[V]) OverlapsPrefixAtDepth(pfx netip.Prefix, depth int) bool { + ip := pfx.Addr() + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + for ; depth < len(octets); depth++ { + if depth > strideCount { + break + } + + octet := octets[depth] + + // full octet path in node trie, check overlap with last prefix octet + if depth == strideCount { + return n.OverlapsIdx(art.PfxToIdx(octet, modBits)) + } + + // test if any route overlaps prefix´ so far + // no best match needed, forward tests without backtracking + if n.PrefixCount() != 0 && n.Contains(art.OctetToIdx(octet)) { + return true + } + + if !n.Children.Test(octet) { + return false + } + + // next child, node or leaf + switch kid := n.MustGetChild(octet).(type) { + case *_NODE_TYPE[V]: + n = kid + continue + + case *LeafNode[V]: + return kid.Prefix.Overlaps(pfx) + + case *FringeNode[V]: + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable: " + pfx.String()) +} + +// OverlapsIdx returns true if the given prefix index overlaps with any entry in this node. +// +// The overlap detection considers three categories: +// +// 1. Whether any stored prefix in this node covers the requested prefix (LPM test) +// 2. Whether the requested prefix covers any stored route in the node +// 3. Whether the requested prefix overlaps with any fringe or child entry +// +// Internally, it leverages precomputed bitsets from the allotment model, +// using fast bitwise set intersections instead of explicit range comparisons. +// This enables high-performance overlap checks on a single stride level +// without descending further into the trie. +func (n *_NODE_TYPE[V]) OverlapsIdx(idx uint8) bool { + // 1. Test if any route in this node overlaps prefix? + if n.Contains(idx) { + return true + } + + // 2. Test if prefix overlaps any route in this node + if n.Prefixes.Intersects(&allot.PfxRoutesLookupTbl[idx]) { + return true + } + + // 3. Test if prefix overlaps any child in this node + return n.Children.Intersects(&allot.FringeRoutesLookupTbl[idx]) +} + +// OverlapsTwoChildren handles all 3x3 combinations of +// node kinds (node, leaf, fringe). +// +// 3x3 possible different combinations for n and o +// +// node, node --> overlaps rec descent +// node, leaf --> overlapsPrefixAtDepth +// node, fringe --> true +// +// leaf, node --> overlapsPrefixAtDepth +// leaf, leaf --> netip.Prefix.Overlaps +// leaf, fringe --> true +// +// fringe, node --> true +// fringe, leaf --> true +// fringe, fringe --> true +func (n *_NODE_TYPE[V]) OverlapsTwoChildren(nChild, oChild any, depth int) bool { + // child type detection + nNode, nIsNode := nChild.(*_NODE_TYPE[V]) + nLeaf, nIsLeaf := nChild.(*LeafNode[V]) + _, nIsFringe := nChild.(*FringeNode[V]) + + oNode, oIsNode := oChild.(*_NODE_TYPE[V]) + oLeaf, oIsLeaf := oChild.(*LeafNode[V]) + _, oIsFringe := oChild.(*FringeNode[V]) + + // Handle all 9 combinations with a single expression + switch { + // NODE cases + case nIsNode && oIsNode: + return nNode.Overlaps(oNode, depth) + case nIsNode && oIsLeaf: + return nNode.OverlapsPrefixAtDepth(oLeaf.Prefix, depth) + case nIsNode && oIsFringe: + return true + + // LEAF cases + case nIsLeaf && oIsNode: + return oNode.OverlapsPrefixAtDepth(nLeaf.Prefix, depth) + case nIsLeaf && oIsLeaf: + return oLeaf.Prefix.Overlaps(nLeaf.Prefix) + case nIsLeaf && oIsFringe: + return true + + // FRINGE cases + case nIsFringe: + return true // fringe overlaps with everything + + default: + panic("logic error, wrong node type combination") + } +} diff --git a/vendor/github.com/gaissmai/bart/internal/nodes/commontests_tmpl.go b/vendor/github.com/gaissmai/bart/internal/nodes/commontests_tmpl.go new file mode 100644 index 0000000..d600ebc --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/nodes/commontests_tmpl.go @@ -0,0 +1,1266 @@ +//go:build generate + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +//go:generate ../../scripts/generate-node-tests.sh + +package nodes + +// ### GENERATE DELETE START ### + +// stub code for generator types and methods +// useful for gopls during development, deleted during go generate + +import ( + "bytes" + "io" + "iter" + "math/rand/v2" + "net/netip" + "slices" + "strings" + "testing" + + "github.com/gaissmai/bart/internal/tests/golden" + "github.com/gaissmai/bart/internal/tests/random" + "github.com/gaissmai/bart/internal/value" +) + +type _NODE_TYPE[V any] struct{} + +func (n *_NODE_TYPE[V]) StatsRec() (_ StatsT) { return } +func (n *_NODE_TYPE[V]) dump(io.Writer, StridePath, int, bool) { return } +func (n *_NODE_TYPE[V]) DumpRec(io.Writer, StridePath, int, bool) { return } +func (n *_NODE_TYPE[V]) FprintRec(io.Writer, TrieItem[V], string) (_ error) { return } +func (n *_NODE_TYPE[V]) Insert(netip.Prefix, V, int) (_ bool) { return } +func (n *_NODE_TYPE[V]) Delete(netip.Prefix) (_ bool) { return } +func (n *_NODE_TYPE[V]) InsertPersist(func(V) V, netip.Prefix, V, int) (_ bool) { return } +func (n *_NODE_TYPE[V]) DeletePersist(func(V) V, netip.Prefix) (_ bool) { return } +func (n *_NODE_TYPE[V]) Subnets(netip.Prefix, func(netip.Prefix, V) bool) { return } +func (n *_NODE_TYPE[V]) Supernets(netip.Prefix, func(netip.Prefix, V) bool) { return } +func (n *_NODE_TYPE[V]) AllRec(StridePath, int, bool, func(netip.Prefix, V) bool) (_ bool) { return } + +func (n *_NODE_TYPE[V]) AllRecSorted(StridePath, int, bool, func(netip.Prefix, V) bool) (_ bool) { + return +} + +// ### GENERATE DELETE END ### + +// helpers +func (n *_NODE_TYPE[V]) all4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if n == nil { + return + } + _ = n.AllRec(StridePath{}, 0, true, yield) + } +} + +func (n *_NODE_TYPE[V]) all6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if n == nil { + return + } + _ = n.AllRec(StridePath{}, 0, false, yield) + } +} + +func (n *_NODE_TYPE[V]) allSorted4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if n == nil { + return + } + _ = n.AllRecSorted(StridePath{}, 0, true, yield) + } +} + +func (n *_NODE_TYPE[V]) allSorted6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if n == nil { + return + } + _ = n.AllRecSorted(StridePath{}, 0, false, yield) + } +} + +func TestInsertDelete__NODE_TYPE(t *testing.T) { + t.Parallel() + + zero := 0 + + testsInsertDelete := []struct { + name string + pfxs []string + is4 bool + wantPfxs int + wantLeaves int + wantFringes int + }{ + { + name: "null", + pfxs: []string{}, + is4: true, + wantPfxs: 0, + wantLeaves: 0, + wantFringes: 0, + }, + { + name: "one prefix in root node", + pfxs: []string{"0.0.0.0/0"}, + is4: true, + wantPfxs: 1, + wantLeaves: 0, + wantFringes: 0, + }, + { + name: "one prefix in root node IPv6", + pfxs: []string{"::/0"}, + is4: false, + wantPfxs: 1, + wantLeaves: 0, + wantFringes: 0, + }, + { + name: "one leaf in root node", + pfxs: []string{"0.0.0.0/32"}, + is4: true, + wantPfxs: 0, + wantLeaves: 1, + wantFringes: 0, + }, + { + name: "one leaf in root node IPv6", + pfxs: []string{"::/32"}, + is4: false, + wantPfxs: 0, + wantLeaves: 1, + wantFringes: 0, + }, + { + name: "one fringe in root node", + pfxs: []string{"0.0.0.0/8"}, + is4: true, + wantPfxs: 0, + wantLeaves: 0, + wantFringes: 1, + }, + { + name: "one fringe in root node IPv6", + pfxs: []string{"0::/8"}, + is4: false, + wantPfxs: 0, + wantLeaves: 0, + wantFringes: 1, + }, + { + name: "many pfxs in root node", + pfxs: []string{"0.0.0.0/0", "0.0.0.0/1", "0.0.0.0/2", "0.0.0.0/3"}, + is4: true, + wantPfxs: 4, + wantLeaves: 0, + wantFringes: 0, + }, + { + name: "many pfxs in root node IPv6", + pfxs: []string{"::/0", "::/1", "::/2", "::/3"}, + is4: false, + wantPfxs: 4, + wantLeaves: 0, + wantFringes: 0, + }, + { + name: "many pfxs and leaves in root node", + pfxs: []string{ + "0.0.0.0/0", "0.0.0.0/1", "0.0.0.0/2", "0.0.0.0/3", // pfxs + "0.0.0.0/9", "1.0.0.0/9", "2.0.0.0/9", "3.0.0.0/9", // leaves + }, + is4: true, + wantPfxs: 4, + wantLeaves: 4, + wantFringes: 0, + }, + { + name: "many pfxs and leaves in root node IPv6", + pfxs: []string{ + "::/0", "::/1", "::/2", "::/3", // pfxs + "::/9", "0100::/9", "0200::/9", "0300::/9", // leaves + }, + is4: false, + wantPfxs: 4, + wantLeaves: 4, + wantFringes: 0, + }, + { + name: "many pfxs, leaves and fringes in root node", + pfxs: []string{ + "0.0.0.0/0", "0.0.0.0/1", // pfxs + "0.0.0.0/9", "1.0.0.0/19", "2.0.0.0/29", // leaves + "4.0.0.0/8", "5.0.0.0/8", "6.0.0.0/8", "7.0.0.0/8", // fringes + }, + is4: true, + wantPfxs: 2, + wantLeaves: 3, + wantFringes: 4, + }, + { + name: "many pfxs, leaves and fringes in root node IPv6", + pfxs: []string{ + "::/0", "::/1", // pfxs + "::/9", "0100::/19", "0200::/29", // leaves + "0400::/8", "0500::/8", "0600::/8", "0700::/8", // fringes + }, + is4: false, + wantPfxs: 2, + wantLeaves: 3, + wantFringes: 4, + }, + { + name: "many pfxs, leaves and fringes in deeper level", + pfxs: []string{ + "0.0.0.0/9", "0.0.0.0/10", // pfxs in level 1 + "0.1.0.0/19", // leaf in level 1 + "0.2.0.0/16", // fringe in level 1 + }, + is4: true, + wantPfxs: 2, + wantLeaves: 1, + wantFringes: 1, + }, + { + name: "many pfxs, leaves and fringes in deeper level IPv6", + pfxs: []string{ + "::/9", "::/10", // pfxs in level 1 + "0010::/19", // leaf in level 1 + "0020::/16", // fringe in level 1 + }, + is4: false, + wantPfxs: 2, + wantLeaves: 1, + wantFringes: 1, + }, + { + name: "leaves and fringes in deeper level", + pfxs: []string{ + "0.0.0.0/12", // pfx in level 1 + "0.0.0.0/16", // fringe in level 1 -> default pfx in level 2 + "0.0.0.0/24", // fringe in level 2 + }, + is4: true, + wantPfxs: 2, + wantLeaves: 0, + wantFringes: 1, + }, + { + name: "leaves and fringes in deeper level IPv6", + pfxs: []string{ + "::/12", // pfx in level 1 + "::/16", // fringe in level 1 -> default pfx in level 2 + "::/24", // fringe in level 2 + }, + is4: false, + wantPfxs: 2, + wantLeaves: 0, + wantFringes: 1, + }, + } + + for _, tt := range testsInsertDelete { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + n := new(_NODE_TYPE[int]) + for _, s := range tt.pfxs { + n.Insert(mpp(s), zero, 0) + n.Insert(mpp(s), zero, 0) // idempotent + } + + stats := n.StatsRec() + if pfxs := stats.Prefixes; pfxs != tt.wantPfxs { + t.Errorf("after insert: got num pfxs %d, want %d", pfxs, tt.wantPfxs) + } + if leaves := stats.Leaves; leaves != tt.wantLeaves { + t.Errorf("after insert: got num leaves %d, want %d", leaves, tt.wantLeaves) + } + if fringes := stats.Fringes; fringes != tt.wantFringes { + t.Errorf("after insert: got num fringes %d, want %d", fringes, tt.wantFringes) + } + + if t.Failed() { + buf := new(strings.Builder) + n.DumpRec(buf, StridePath{}, 0, tt.is4) + t.Logf("%s:\n%s", tt.name, buf.String()) + } + + // delete all prefixes + + for _, s := range tt.pfxs { + n.Delete(mpp(s)) + n.Delete(mpp(s)) // idempotent + } + + stats = n.StatsRec() + if num := stats.Prefixes; num != 0 { + t.Errorf("after delete: got num pfxs %d, want 0", num) + } + if num := stats.Leaves; num != 0 { + t.Errorf("after delete: got num leaves %d, want 0", num) + } + if num := stats.Fringes; num != 0 { + t.Errorf("after delete: got num fringes %d, want 0", num) + } + + if t.Failed() { + buf := new(strings.Builder) + n.DumpRec(buf, StridePath{}, 0, tt.is4) + t.Logf("%s:\n%s", tt.name, buf.String()) + } + }) + + t.Run("Persist_"+tt.name, func(t *testing.T) { + t.Parallel() + + n := new(_NODE_TYPE[int]) + + for _, s := range tt.pfxs { + n.InsertPersist(nil, mpp(s), zero, 0) + n.InsertPersist(nil, mpp(s), zero, 0) // idempotent + } + + stats := n.StatsRec() + if pfxs := stats.Prefixes; pfxs != tt.wantPfxs { + t.Errorf("after insert: got num pfxs %d, want %d", pfxs, tt.wantPfxs) + } + if leaves := stats.Leaves; leaves != tt.wantLeaves { + t.Errorf("after insert: got num leaves %d, want %d", leaves, tt.wantLeaves) + } + if fringes := stats.Fringes; fringes != tt.wantFringes { + t.Errorf("after insert: got num fringes %d, want %d", fringes, tt.wantFringes) + } + + if t.Failed() { + buf := new(strings.Builder) + n.DumpRec(buf, StridePath{}, 0, tt.is4) + t.Logf("%s:\n%s", tt.name, buf.String()) + } + + // delete all prefixes + + for _, s := range tt.pfxs { + n.DeletePersist(nil, mpp(s)) + n.DeletePersist(nil, mpp(s)) // idempotent + } + + stats = n.StatsRec() + if num := stats.Prefixes; num != 0 { + t.Errorf("after delete: got num pfxs %d, want 0", num) + } + if num := stats.Leaves; num != 0 { + t.Errorf("after delete: got num leaves %d, want 0", num) + } + if num := stats.Fringes; num != 0 { + t.Errorf("after delete: got num fringes %d, want 0", num) + } + + if t.Failed() { + buf := new(strings.Builder) + n.DumpRec(buf, StridePath{}, 0, tt.is4) + t.Logf("%s:\n%s", tt.name, buf.String()) + } + }) + } +} + +func TestAllIterators__NODE_TYPE(t *testing.T) { + t.Parallel() + n := workLoadN() + + prng := rand.New(rand.NewPCG(42, 42)) + + for range 10 { + pfxs := random.RealWorldPrefixes4(prng, n) + + node := new(_NODE_TYPE[int]) + for _, p := range pfxs { + node.Insert(p, 0, 0) + } + + // AllRec: collect without order guarantee + var got []netip.Prefix + i := 0 + for p := range node.all4() { + i++ + got = append(got, p) + if i >= n/2 { + break + } + } + + if len(got) != n/2 { + t.Fatalf("AllRec len=%d, want %d", len(got), n/2) + } + + got = nil + i = 0 + for p := range node.allSorted4() { + i++ + got = append(got, p) + if i >= n/2 { + break + } + } + + if len(got) != n/2 { + t.Fatalf("AllRecSorted len=%d, want %d", len(got), n/2) + } + + slices.SortFunc(pfxs, CmpPrefix) + if !slices.Equal(pfxs[:n/2], got) { + t.Fatal("AllRecSorted is not as expected") + } + } +} + +func TestSupernets4__NODE_TYPE(t *testing.T) { + t.Parallel() + n := workLoadN() + prng := rand.New(rand.NewPCG(42, 42)) + + for range 10 { + pfxs := random.RealWorldPrefixes4(prng, n) + + node := new(_NODE_TYPE[int]) + gold := new(golden.Table[int]) + + for i, pfx := range pfxs { + node.Insert(pfx, i, 0) + gold.Insert(pfx, i) + } + + // test with random probes + for _, probe := range pfxs { + goldSupernets := gold.Supernets(probe) + nodeSupernets := []netip.Prefix{} + + node.Supernets(probe, func(p netip.Prefix, _ int) bool { + nodeSupernets = append(nodeSupernets, p) + return true + }) + + if !slices.Equal(goldSupernets, nodeSupernets) { + t.Errorf("Supernets expected equal to golden implementation") + } + } + } +} + +func TestSupernets6__NODE_TYPE(t *testing.T) { + t.Parallel() + n := workLoadN() + prng := rand.New(rand.NewPCG(42, 42)) + + for range 10 { + pfxs := random.RealWorldPrefixes6(prng, n) + + node := new(_NODE_TYPE[int]) + gold := new(golden.Table[int]) + + for i, pfx := range pfxs { + node.Insert(pfx, i, 0) + gold.Insert(pfx, i) + } + + // test with random probes + for _, probe := range pfxs { + goldSupernets := gold.Supernets(probe) + nodeSupernets := []netip.Prefix{} + + node.Supernets(probe, func(p netip.Prefix, _ int) bool { + nodeSupernets = append(nodeSupernets, p) + return true + }) + + if !slices.Equal(goldSupernets, nodeSupernets) { + t.Errorf("Supernets expected equal to golden implementation") + } + } + } +} + +func TestSubnets4__NODE_TYPE(t *testing.T) { + t.Parallel() + n := workLoadN() + prng := rand.New(rand.NewPCG(42, 42)) + + for range 10 { + pfxs := random.RealWorldPrefixes4(prng, n) + + node := new(_NODE_TYPE[int]) + gold := new(golden.Table[int]) + + for i, pfx := range pfxs { + node.Insert(pfx, i, 0) + gold.Insert(pfx, i) + } + + // the default route must have all pfxs as subnet + defaultRoute := mpp("0.0.0.0/0") + allPfxsSorted := slices.Clone(pfxs) + slices.SortFunc(allPfxsSorted, CmpPrefix) + + nodeSubnets := []netip.Prefix{} + node.Subnets(defaultRoute, func(p netip.Prefix, _ int) bool { + nodeSubnets = append(nodeSubnets, p) + return true + }) + + if !slices.Equal(allPfxsSorted, nodeSubnets) { + t.Errorf("Subnets(%s) not equal to all sorted prefixes", defaultRoute) + } + + kMax := max(1, n/10) + somePfxs := make([]netip.Prefix, 0, kMax) // allocate mem 1x + + for k := range kMax { + somePfxs = somePfxs[:0] // reset slice + + i := 0 + node.Subnets(defaultRoute, func(p netip.Prefix, _ int) bool { + if i >= k { + // early-termination: stop after k + return false + } + i++ + somePfxs = append(somePfxs, p) + return true + }) + + if len(somePfxs) != k { + t.Errorf("Subnets early-termination: got %d items, want %d", len(somePfxs), k) + } + + if !slices.Equal(somePfxs, allPfxsSorted[:k]) { + t.Errorf("Subnets expected equal") + } + } + + // test with random probes + for _, probe := range pfxs { + goldSubnets := gold.Subnets(probe) + nodeSubnets := []netip.Prefix{} + + node.Subnets(probe, func(p netip.Prefix, _ int) bool { + nodeSubnets = append(nodeSubnets, p) + return true + }) + + if !slices.Equal(goldSubnets, nodeSubnets) { + t.Errorf("Subnets expected equal to golden implementation") + } + } + } +} + +func TestSubnets6__NODE_TYPE(t *testing.T) { + t.Parallel() + n := workLoadN() + prng := rand.New(rand.NewPCG(42, 42)) + + for range 10 { + pfxs := random.RealWorldPrefixes6(prng, n) + + node := new(_NODE_TYPE[int]) + gold := new(golden.Table[int]) + + for i, pfx := range pfxs { + node.Insert(pfx, i, 0) + gold.Insert(pfx, i) + } + + // the default route must have all pfxs as subnet + defaultRoute := mpp("::/0") + allPfxsSorted := slices.Clone(pfxs) + slices.SortFunc(allPfxsSorted, CmpPrefix) + + nodeSubnets := []netip.Prefix{} + node.Subnets(defaultRoute, func(p netip.Prefix, _ int) bool { + nodeSubnets = append(nodeSubnets, p) + return true + }) + + if !slices.Equal(allPfxsSorted, nodeSubnets) { + t.Errorf("Subnets(%s) not equal to all sorted prefixes", defaultRoute) + } + + kMax := max(1, n/10) + somePfxs := make([]netip.Prefix, 0, kMax) // allocate mem 1x + + for k := range kMax { + somePfxs = somePfxs[:0] // reset slice + + i := 0 + node.Subnets(defaultRoute, func(p netip.Prefix, _ int) bool { + if i >= k { + // early-termination: stop after k + return false + } + i++ + somePfxs = append(somePfxs, p) + return true + }) + + if len(somePfxs) != k { + t.Errorf("Subnets early-termination: got %d items, want %d", len(somePfxs), k) + } + + if !slices.Equal(somePfxs, allPfxsSorted[:k]) { + t.Errorf("Subnets expected equal") + } + } + + // test with random probes + for _, probe := range pfxs { + goldSubnets := gold.Subnets(probe) + nodeSubnets := []netip.Prefix{} + + node.Subnets(probe, func(p netip.Prefix, _ int) bool { + nodeSubnets = append(nodeSubnets, p) + return true + }) + + if !slices.Equal(goldSubnets, nodeSubnets) { + t.Errorf("Subnets expected equal to golden implementation") + } + } + } +} + +// TestDump_ZST verifies that dump does not print values when V is a zero-sized type. +func TestDump_ZST__NODE_TYPE(t *testing.T) { + t.Parallel() + + node := new(_NODE_TYPE[struct{}]) + + // Insert prefix to populate the node + pfx := mpp("10.0.0.0/7") + node.Insert(pfx, struct{}{}, 0) + + var buf strings.Builder + path := StridePath{} + node.dump(&buf, path, 0, true) + + output := buf.String() + + // For ZST, dump should print prefixes(#N) but skip the "values(#N):" section + if !strings.Contains(output, "prefxs(") { + t.Errorf("Expected 'prefxs()' section, but not found in:\n%s", output) + } + + // For ZST, dump should print prefxs(#N) but skip the "values(#N):" section + if strings.Contains(output, "values(") { + t.Errorf("Expected no 'values()' section for ZST, but found it in:\n%s", output) + } +} + +// TestDump_NonZST verifies that dump prints values when V is not a zero-sized type. +func TestDump_NonZST__NODE_TYPE(t *testing.T) { + t.Parallel() + + node := new(_NODE_TYPE[int]) + + // Skip for LiteNode (no real payload) + if _, isLite := any(node).(*LiteNode[int]); isLite { + t.Skip("LiteNode has no real payload") + } + + pfx := mpp("10.0.0.0/7") + node.Insert(pfx, 42, 0) + + var buf strings.Builder + path := StridePath{} + node.dump(&buf, path, 0, true) + + output := buf.String() + + // dump should include the "prefxs(#N):" section + if !strings.Contains(output, "prefxs(") { + t.Errorf("Expected 'prefxs()' section, but not found in:\n%s", output) + } + + // For non-ZST, dump should include the "values(#N):" section + if !strings.Contains(output, "values(") { + t.Errorf("Expected 'values()' section for non-ZST, but not found in:\n%s", output) + } + + // Should contain the actual value + if !strings.Contains(output, "42") { + t.Errorf("Expected value '42' in output, but not found in:\n%s", output) + } +} + +// TestFprintRec_ZST verifies FprintRec does not print values for zero-sized types. +func TestFprintRec_ZST__NODE_TYPE(t *testing.T) { + t.Parallel() + + node := new(_NODE_TYPE[struct{}]) + + pfx := mpp("10.0.0.0/7") + node.Insert(pfx, struct{}{}, 0) + + parent := TrieItem[struct{}]{ + Node: nil, + Is4: true, + Path: StridePath{}, + Depth: 0, + Idx: 0, + Cidr: mpp("0.0.0.0/0"), + } + + var buf bytes.Buffer + if err := node.FprintRec(&buf, parent, ""); err != nil { + t.Fatalf("FprintRec failed: %v", err) + } + + output := buf.String() + + // For ZST, output should show prefix but no value in parentheses + if strings.Contains(output, "10.0.0.0/7 (") || strings.Contains(output, "10.0.0.0/7(") { + t.Errorf("Expected no value in parentheses for ZST prefix, but found in:\n%s", output) + } +} + +// TestFprintRec_NonZST verifies FprintRec prints values for non-zero-sized types. +func TestFprintRec_NonZST__NODE_TYPE(t *testing.T) { + t.Parallel() + + node := new(_NODE_TYPE[string]) + + // Skip for LiteNode (no real payload) + if _, isLite := any(node).(*LiteNode[string]); isLite { + t.Skip("LiteNode has no real payload") + } + + pfx := mpp("10.0.0.0/7") + node.Insert(pfx, "testval", 0) + + parent := TrieItem[string]{ + Node: nil, + Is4: true, + Path: StridePath{}, + Depth: 0, + Idx: 0, + Cidr: mpp("0.0.0.0/0"), + Val: "Default Gateway", + } + + var buf bytes.Buffer + + if err := node.FprintRec(&buf, parent, ""); err != nil { + t.Fatalf("FprintRec failed: %v", err) + } + + output := buf.String() + + // For non-ZST, output should show both prefix and value + if !strings.Contains(output, "10.0.0.0/7") || !strings.Contains(output, "testval") { + t.Errorf("Expected prefix and value 'testval' in output, but got:\n%s", output) + } +} + +// TestEqualRec__NODE_TYPE tests the recursive node equality comparison. +func TestEqualRec__NODE_TYPE(t *testing.T) { + t.Parallel() + + // nil checks + var nilNode1, nilNode2 *_NODE_TYPE[int] + if !nilNode1.EqualRec(nilNode2) { + t.Error("nil nodes should be equal") + } + + n1 := new(_NODE_TYPE[int]) + if n1.EqualRec(nilNode1) { + t.Error("non-nil node should not be equal to nil") + } + if nilNode1.EqualRec(n1) { + t.Error("nil node should not be equal to non-nil") + } + + // identical nodes + if !n1.EqualRec(n1) { + t.Error("node should be equal to itself") + } + + // different prefix bitsets + n2 := new(_NODE_TYPE[int]) + n1.Insert(mpp("10.0.0.0/7"), 42, 0) + if n1.EqualRec(n2) { + t.Error("nodes with different prefixes should not be equal") + } + + // different values + // Skip for LiteNode because it has no real payload values + if _, isLite := any(n1).(*LiteNode[int]); !isLite { + n2.Insert(mpp("10.0.0.0/7"), 43, 0) + if n1.EqualRec(n2) { + t.Error("nodes with same prefixes but different values should not be equal") + } + } + + // same prefix and value + n2_same := new(_NODE_TYPE[int]) + n2_same.Insert(mpp("10.0.0.0/7"), 42, 0) + if _, isLite := any(n1).(*LiteNode[int]); !isLite { + if !n1.EqualRec(n2_same) { + t.Error("nodes with same prefixes and values should be equal") + } + } + + // different children bitsets + n3 := new(_NODE_TYPE[int]) + n4 := new(_NODE_TYPE[int]) + n3.Insert(mpp("10.0.0.0/8"), 42, 0) // this is a fringe node at depth 1, and inserts into Children + if n3.EqualRec(n4) { + t.Error("nodes with different children should not be equal") + } + + // fringe nodes with different values + if _, isLite := any(n3).(*LiteNode[int]); !isLite { + n4.Insert(mpp("10.0.0.0/8"), 43, 0) + if n3.EqualRec(n4) { + t.Error("nodes with different fringe values should not be equal") + } + } + + // leaf nodes with different prefixes/values + n5 := new(_NODE_TYPE[int]) + n6 := new(_NODE_TYPE[int]) + n5.Insert(mpp("10.20.0.0/15"), 42, 0) // leaf node at depth 1 + n6.Insert(mpp("10.30.0.0/15"), 42, 0) // different leaf node prefix + if n5.EqualRec(n6) { + t.Error("nodes with different leaf prefixes should not be equal") + } + + if _, isLite := any(n5).(*LiteNode[int]); !isLite { + n7 := new(_NODE_TYPE[int]) + n7.Insert(mpp("10.20.0.0/15"), 43, 0) // different leaf value + if n5.EqualRec(n7) { + t.Error("nodes with different leaf values should not be equal") + } + } +} + +// TestOverlapsExtra__NODE_TYPE tests specific edge cases in trie overlap detection. +func TestOverlapsExtra__NODE_TYPE(t *testing.T) { + t.Parallel() + + // 1. Test OverlapsSameChildren loop continuation & completion (returning false) + t.Run("same_children_no_overlap", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n2 := new(_NODE_TYPE[int]) + + // Insert disjoint child subnets at address 10 and 20 + n1.Insert(mpp("10.10.1.0/24"), 42, 0) + n1.Insert(mpp("10.20.1.0/24"), 42, 0) + + n2.Insert(mpp("10.10.2.0/24"), 42, 0) + n2.Insert(mpp("10.20.2.0/24"), 42, 0) + + if n1.Overlaps(n2, 0) { + t.Error("expected no overlap between disjoint child subnets") + } + }) + + // 2. Test OverlapsSameChildren loop continuation & early exit (returning true) + t.Run("same_children_first_no_overlap_second_overlap", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n2 := new(_NODE_TYPE[int]) + + // Address 10 does not overlap, address 20 does overlap + n1.Insert(mpp("10.10.1.0/24"), 42, 0) + n1.Insert(mpp("10.20.1.0/24"), 42, 0) + + n2.Insert(mpp("10.10.2.0/24"), 42, 0) + n2.Insert(mpp("10.20.1.0/24"), 42, 0) // overlap here + + if !n1.Overlaps(n2, 0) { + t.Error("expected overlap since second child subnet overlaps") + } + }) + + // 3. Test OverlapsSameChildren with matching child at address 255 that does not overlap + t.Run("same_children_boundary_255_no_overlap", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n2 := new(_NODE_TYPE[int]) + + n1.Insert(mpp("10.255.1.0/24"), 42, 0) + n2.Insert(mpp("10.255.2.0/24"), 42, 0) + + if n1.Overlaps(n2, 0) { + t.Error("expected no overlap on boundary 255") + } + }) + + // 4. Test OverlapsPrefixAtDepth with LeafNode and FringeNode + t.Run("prefix_overlaps_leaf_node_true", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n1.Insert(mpp("10.20.0.0/15"), 42, 0) + + if !n1.OverlapsPrefixAtDepth(mpp("10.20.0.0/16"), 0) { + t.Error("expected overlap with leaf node prefix") + } + }) + + t.Run("prefix_overlaps_leaf_node_false", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n1.Insert(mpp("10.20.0.0/15"), 42, 0) + + if n1.OverlapsPrefixAtDepth(mpp("10.30.0.0/16"), 0) { + t.Error("expected no overlap with disjoint prefix") + } + }) + + t.Run("prefix_overlaps_fringe_node", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n1.Insert(mpp("10.0.0.0/8"), 42, 0) + + if !n1.OverlapsPrefixAtDepth(mpp("10.0.0.0/16"), 0) { + t.Error("expected overlap with fringe node") + } + }) + + // 5. Test OverlapsPrefixAtDepth with deeper path walk + t.Run("prefix_overlaps_idx_at_last_octet", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n1.Insert(mpp("10.20.30.0/24"), 42, 0) + + if !n1.OverlapsPrefixAtDepth(mpp("10.20.0.0/16"), 0) { + t.Error("expected overlap at last octet") + } + }) + + t.Run("prefix_overlaps_contains_at_depth", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n1.Insert(mpp("10.128.30.0/24"), 42, 0) + n1.Insert(mpp("10.128.0.0/9"), 42, 0) + + if !n1.OverlapsPrefixAtDepth(mpp("10.128.30.0/24"), 0) { + t.Error("expected overlap with contains check at depth 1") + } + }) +} + +// TestDumpStringExtra__NODE_TYPE tests type classification in DumpString and DumpRec. +func TestDumpStringExtra__NODE_TYPE(t *testing.T) { + t.Parallel() + + // 1. Create a halfNode at the root + n1 := new(_NODE_TYPE[int]) + // LeafNode under child slot 10: + n1.Insert(mpp("10.20.0.0/15"), 42, 0) + // Internal node under child slot 11 (requires branching to prevent path compression): + n1.Insert(mpp("11.30.40.0/24"), 42, 0) + n1.Insert(mpp("11.30.50.0/24"), 42, 0) + + dump1 := n1.DumpString(nil, 0, true) + if !strings.Contains(dump1, "HALF") { + t.Errorf("expected HALF node type in dump, got:\n%s", dump1) + } + + // 2. Create a pathNode at the root + n2 := new(_NODE_TYPE[int]) + // Branching paths under child slot 10 to create an internal node at root child 10 + n2.Insert(mpp("10.20.30.0/24"), 42, 0) + n2.Insert(mpp("10.20.40.0/24"), 42, 0) + + dump2 := n2.DumpString(nil, 0, true) + if !strings.Contains(dump2, "PATH") { + t.Errorf("expected PATH node type in dump, got:\n%s", dump2) + } + + // 3. Test DumpRec on nil/empty node + var nilNode *_NODE_TYPE[int] + var buf bytes.Buffer + nilNode.DumpRec(&buf, StridePath{}, 0, true) + if buf.Len() != 0 { + t.Error("expected empty buffer for nil DumpRec") + } + + buf.Reset() + emptyNode := new(_NODE_TYPE[int]) + emptyNode.DumpRec(&buf, StridePath{}, 0, true) + if buf.Len() != 0 { + t.Error("expected empty buffer for empty DumpRec") + } +} + +// TestDeletePurgeExtra__NODE_TYPE tests the bottom-up trie compression on delete. +func TestDeletePurgeExtra__NODE_TYPE(t *testing.T) { + t.Parallel() + + // 1. Trigger PurgeAndCompress: case childCount == 1 with LeafNode + t.Run("purge_leaf_node", func(t *testing.T) { + t.Parallel() + n := new(_NODE_TYPE[int]) + n.Insert(mpp("10.20.10.0/24"), 42, 0) + n.Insert(mpp("10.20.20.0/24"), 42, 0) + + n.Delete(mpp("10.20.20.0/24")) + + if _, ok := n.Get(mpp("10.20.10.0/24")); !ok { + t.Error("expected remaining leaf node to be present") + } + }) + + // 2. Trigger PurgeAndCompress: case childCount == 1 with FringeNode + t.Run("purge_fringe_node", func(t *testing.T) { + t.Parallel() + n := new(_NODE_TYPE[int]) + n.Insert(mpp("10.20.0.0/16"), 42, 0) + n.Insert(mpp("10.30.0.0/16"), 42, 0) + + n.Delete(mpp("10.30.0.0/16")) + + if _, ok := n.Get(mpp("10.20.0.0/16")); !ok { + t.Error("expected remaining fringe node to be present") + } + }) + + // 3. Trigger PurgeAndCompress: case pfxCount == 1 + t.Run("purge_single_prefix", func(t *testing.T) { + t.Parallel() + n := new(_NODE_TYPE[int]) + n.Insert(mpp("10.20.0.0/16"), 42, 0) + n.Insert(mpp("10.0.0.0/8"), 42, 0) + + n.Delete(mpp("10.20.0.0/16")) + + if _, ok := n.Get(mpp("10.0.0.0/8")); !ok { + t.Error("expected remaining prefix to be present") + } + }) +} + +// TestUnionRecExtra__NODE_TYPE tests specific edge cases in trie Union operations. +func TestUnionRecExtra__NODE_TYPE(t *testing.T) { + t.Parallel() + + _, isLite := any(new(_NODE_TYPE[int])).(*LiteNode[int]) + + // 1. Cover handleMatrix case 2: thisIsNode && otherIsLeaf, where leaf already exists in thisNode + t.Run("node_leaf_exists", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n2 := new(_NODE_TYPE[int]) + + // Both n1 and n2 have child at octet 10, but: + // n1's child is an internal node (requires branching to prevent path compression) + n1.Insert(mpp("10.10.10.0/24"), 42, 0) + n1.Insert(mpp("10.10.20.0/24"), 42, 0) + + // n2's child is a LeafNode with "10.10.20.0/24" + n2.Insert(mpp("10.10.20.0/24"), 43, 0) + + n1.UnionRec(value.CloneFnFactory[int](), n2, 0) + + val, ok := n1.Get(mpp("10.10.20.0/24")) + if !ok { + t.Fatal("expected prefix to exist") + } + if !isLite && val != 43 { + t.Errorf("expected value 43, got %v", val) + } + }) + + // 2. Cover handleMatrix case 2: thisIsNode && otherIsFringe, where fringe already exists in thisNode + t.Run("node_fringe_exists", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n2 := new(_NODE_TYPE[int]) + + // Both n1 and n2 have child at octet 10. + // n1's child is an internal node and contains the default route/fringe "10.0.0.0/8" + n1.Insert(mpp("10.10.10.0/24"), 42, 0) + n1.Insert(mpp("10.0.0.0/8"), 42, 0) + + // n2's child is a FringeNode "10.0.0.0/8" + n2.Insert(mpp("10.0.0.0/8"), 43, 0) + + n1.UnionRec(value.CloneFnFactory[int](), n2, 0) + + val, ok := n1.Get(mpp("10.0.0.0/8")) + if !ok { + t.Fatal("expected prefix to exist") + } + if !isLite && val != 43 { + t.Errorf("expected value 43, got %v", val) + } + }) + + // 3. Cover handleMatrixPersist case 2 counterpart + t.Run("node_leaf_exists_persist", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n2 := new(_NODE_TYPE[int]) + + n1.Insert(mpp("10.10.10.0/24"), 42, 0) + n1.Insert(mpp("10.10.20.0/24"), 42, 0) + + n2.Insert(mpp("10.10.20.0/24"), 43, 0) + + n1.UnionRecPersist(value.CloneFnFactory[int](), n2, 0) + + val, ok := n1.Get(mpp("10.10.20.0/24")) + if !ok { + t.Fatal("expected prefix to exist") + } + if !isLite && val != 43 { + t.Errorf("expected value 43, got %v", val) + } + }) + + t.Run("node_fringe_exists_persist", func(t *testing.T) { + t.Parallel() + n1 := new(_NODE_TYPE[int]) + n2 := new(_NODE_TYPE[int]) + + n1.Insert(mpp("10.10.10.0/24"), 42, 0) + n1.Insert(mpp("10.0.0.0/8"), 42, 0) + + n2.Insert(mpp("10.0.0.0/8"), 43, 0) + + n1.UnionRecPersist(value.CloneFnFactory[int](), n2, 0) + + val, ok := n1.Get(mpp("10.0.0.0/8")) + if !ok { + t.Fatal("expected prefix to exist") + } + if !isLite && val != 43 { + t.Errorf("expected value 43, got %v", val) + } + }) +} + +// TestSubnetsEarlyExit__NODE_TYPE tests early termination in Subnets traversal. +func TestSubnetsEarlyExit__NODE_TYPE(t *testing.T) { + t.Parallel() + + n := new(_NODE_TYPE[int]) + n.Insert(mpp("10.0.0.0/8"), 1, 0) + n.Insert(mpp("10.10.10.0/24"), 2, 0) + n.Insert(mpp("10.10.20.0/24"), 3, 0) + n.Insert(mpp("10.20.0.0/15"), 4, 0) + + // Traversal 1: yield returns false immediately + yieldCount := 0 + n.Subnets(mpp("10.0.0.0/8"), func(pfx netip.Prefix, val int) bool { + yieldCount++ + return false // stop immediately + }) + + if yieldCount != 1 { + t.Errorf("expected yieldCount to be 1, got %d", yieldCount) + } + + // Traversal 2: yield returns false after 2 items + yieldCount = 0 + n.Subnets(mpp("10.0.0.0/8"), func(pfx netip.Prefix, val int) bool { + yieldCount++ + if yieldCount == 2 { + return false + } + return true + }) + + if yieldCount != 2 { + t.Errorf("expected yieldCount to be 2, got %d", yieldCount) + } +} + +// TestSupernetsExtra__NODE_TYPE tests specific edge cases and early exits in Supernets traversal. +func TestSupernetsExtra__NODE_TYPE(t *testing.T) { + t.Parallel() + + n := new(_NODE_TYPE[int]) + // LeafNode at depth 1: + n.Insert(mpp("10.20.0.0/15"), 1, 0) + // FringeNode at depth 1: + n.Insert(mpp("10.30.0.0/16"), 2, 0) + // Normal prefixes: + n.Insert(mpp("10.0.0.0/8"), 3, 0) + n.Insert(mpp("10.40.50.0/24"), 4, 0) + + // 1. LeafNode longer prefix check + yielded := []netip.Prefix{} + n.Supernets(mpp("10.20.0.0/15"), func(pfx netip.Prefix, val int) bool { + yielded = append(yielded, pfx) + return true + }) + if len(yielded) != 2 { + t.Errorf("expected 2 supernets, got %v", yielded) + } + + // 2. FringeNode longer prefix check + yielded = []netip.Prefix{} + n.Supernets(mpp("10.30.0.0/16"), func(pfx netip.Prefix, val int) bool { + yielded = append(yielded, pfx) + return true + }) + if len(yielded) != 2 { + t.Errorf("expected 2 supernets, got %v", yielded) + } + + // 3. Early exits on yield + // LeafNode yield false + yieldCount := 0 + n.Supernets(mpp("10.20.0.0/15"), func(pfx netip.Prefix, val int) bool { + yieldCount++ + if pfx == mpp("10.20.0.0/15") { + return false + } + return true + }) + if yieldCount != 1 { + t.Errorf("expected yieldCount 1 on leaf early exit, got %d", yieldCount) + } + + // FringeNode yield false + yieldCount = 0 + n.Supernets(mpp("10.30.0.0/16"), func(pfx netip.Prefix, val int) bool { + yieldCount++ + if pfx == mpp("10.30.0.0/16") { + return false + } + return true + }) + if yieldCount != 1 { + t.Errorf("expected yieldCount 1 on fringe early exit, got %d", yieldCount) + } + + // Backtracking yield false + yieldCount = 0 + n.Supernets(mpp("10.40.50.0/24"), func(pfx netip.Prefix, val int) bool { + yieldCount++ + return false + }) + if yieldCount != 1 { + t.Errorf("expected yieldCount 1 on backtracking early exit, got %d", yieldCount) + } + + // 4. Trigger depth > strideCount + yielded = []netip.Prefix{} + n.Supernets(mpp("10.40.0.0/16"), func(pfx netip.Prefix, val int) bool { + yielded = append(yielded, pfx) + return true + }) + if len(yielded) != 1 || yielded[0] != mpp("10.0.0.0/8") { + t.Errorf("expected only 10.0.0.0/8, got %v", yielded) + } +} diff --git a/vendor/github.com/gaissmai/bart/internal/nodes/fast.go b/vendor/github.com/gaissmai/bart/internal/nodes/fast.go new file mode 100644 index 0000000..fdc5185 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/nodes/fast.go @@ -0,0 +1,286 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package nodes + +import ( + "iter" + + "github.com/gaissmai/bart/internal/lpm" + "github.com/gaissmai/bart/internal/sparse" +) + +// FastNode is based on [BartNode], but it also uses a cache ([256]uint8) +// per node to speed up traversal of the multi-bit trie. +// Lookups become faster, but this requires more memory per prefix, +// and updates (insertions/deletions) also become slower due to the +// overhead of managing the cache. +type FastNode[V any] struct { + Prefixes sparse.Array256[V] + Children sparse.Array256[any] + // map addr to slice idx (aka rank) + childRankCache [256]uint8 +} + +// IsEmpty returns true if the node contains no routing entries (prefixes) +// and no child nodes. Empty nodes are candidates for compression or removal +// during trie optimization. +func (n *FastNode[V]) IsEmpty() bool { + if n == nil { + return true + } + return n.Prefixes.Len() == 0 && n.Children.Len() == 0 +} + +// PrefixCount returns the number of prefixes stored in this node. +func (n *FastNode[V]) PrefixCount() int { + return n.Prefixes.Len() +} + +// ChildCount returns the number of slots used in this node. +func (n *FastNode[V]) ChildCount() int { + return n.Children.Len() +} + +// InsertPrefix adds or updates a routing entry at the specified index with the given value. +// It returns true if a prefix already existed at that index (indicating an update), +// false if this is a new insertion. +func (n *FastNode[V]) InsertPrefix(idx uint8, val V) (exists bool) { + _, exists = n.Prefixes.InsertAt(idx, val) + return +} + +// GetPrefix retrieves the value associated with the prefix at the given index. +// Returns the value and true if found, or zero value and false if not present. +func (n *FastNode[V]) GetPrefix(idx uint8) (val V, exists bool) { + return n.Prefixes.Get(idx) +} + +// MustGetPrefix retrieves the value at the specified index, panicking if not found. +// This method should only be used when the caller is certain the index exists. +func (n *FastNode[V]) MustGetPrefix(idx uint8) (val V) { + return n.Prefixes.MustGet(idx) +} + +// AllIndices returns an iterator over all prefix entries. +// Each iteration yields the prefix index (uint8) and its associated value (V). +func (n *FastNode[V]) AllIndices() iter.Seq2[uint8, V] { + return func(yield func(uint8, V) bool) { + var buf [256]uint8 + for i, idx := range n.Prefixes.AsSlice(&buf) { + if !yield(idx, n.Prefixes.Items[i]) { + return + } + } + } +} + +// DeletePrefix removes the prefix at the specified index. +// Returns true if the prefix existed, otherwise false. +func (n *FastNode[V]) DeletePrefix(idx uint8) (exists bool) { + _, exists = n.Prefixes.DeleteAt(idx) + return exists +} + +// InsertChild adds a child node at the specified address (0-255). +// The child can be a *FastNode[V], *LeafNode[V], or *FringeNode[V]. +// Returns true if a child already existed at that address. +func (n *FastNode[V]) InsertChild(addr uint8, child any) (exists bool) { + var rank0 int + rank0, exists = n.Children.InsertAt(addr, child) + if exists { + // Update only: the value at addr is overwritten in-place by InsertAt. + // childRankCache[addr] is not refreshed because the rank is unchanged + // the position of addr in the sparse slice does not shift on an update. + return + } + + // new child inserted? cache the rank value for this addr + //nolint:gosec // G115: integer overflow conversion int -> uint8 + n.childRankCache[addr] = uint8(rank0) + + // increment all cached ranks after addr + for i := 255; i > int(addr); i-- { + n.childRankCache[i]++ + } + return +} + +// DeleteChild removes the child node at the specified address. +// This operation is idempotent - removing a non-existent child is safe. +func (n *FastNode[V]) DeleteChild(addr uint8) (exists bool) { + _, exists = n.Children.DeleteAt(addr) + + // nothing deleted + if !exists { + return exists + } + + // decrement all cached ranks after addr + for i := 255; i > int(addr); i-- { + n.childRankCache[i]-- + } + + return exists +} + +// GetChild retrieves the child node at the specified address. +// Returns the child and true if found, or nil and false if not present. +func (n *FastNode[V]) GetChild(addr uint8) (any, bool) { + if n.Children.Test(addr) { + rank0 := n.childRankCache[addr] + return n.Children.Items[rank0], true + } + return nil, false +} + +// MustGetChild retrieves the child at addr using the pre-cached rank stored in +// childRankCache[addr] for a direct O(1) array access without an existence check. +// +// The caller must guarantee that addr is present (Children.Test(addr) == true). +// If addr is absent, childRankCache[addr] contains the number of occupied +// addresses less than addr (maintained by InsertChild/DeleteChild), so the +// behaviour is undefined: either a wrong child is returned silently, or the +// call panics with an index-out-of-range error. +func (n *FastNode[V]) MustGetChild(addr uint8) any { + rank0 := n.childRankCache[addr] + return n.Children.Items[rank0] +} + +// AllChildren returns an iterator over all child nodes. +// Each iteration yields the child's address (uint8) and the child node (any). +func (n *FastNode[V]) AllChildren() iter.Seq2[uint8, any] { + return func(yield func(addr uint8, child any) bool) { + var buf [256]uint8 + addrs := n.Children.AsSlice(&buf) + for i, addr := range addrs { + if !yield(addr, n.Children.Items[i]) { + return + } + } + } +} + +// Contains returns true if an index (idx) has any matching longest-prefix +// in the current node’s prefix table. +// +// This function performs a presence check without retrieving the associated value. +// It is faster than a full lookup, as it only tests for intersection with the +// backtracking bitset for the given index. +// +// The prefix table is structured as a complete binary tree (CBT), and LPM testing +// is done via a bitset operation that maps the traversal path from the given index +// toward its possible ancestors. +func (n *FastNode[V]) Contains(idx uint8) bool { + return n.Prefixes.Intersects(&lpm.LookupTbl[idx]) +} + +// LookupIdx performs a longest-prefix match (LPM) lookup for the given index (idx) +// within the 8-bit stride-based prefix table at this trie depth. +// +// The function returns the matched base index, associated value, and true if a +// matching prefix exists at this level; otherwise, ok is false. +// +// Internally, the prefix table is organized as a complete binary tree (CBT) indexed +// via the baseIndex function. Unlike the original ART algorithm, this implementation +// does not use an allotment-based approach. Instead, it performs CBT backtracking +// using a bitset-based operation with a precomputed backtracking pattern specific to idx. +func (n *FastNode[V]) LookupIdx(idx uint8) (top uint8, val V, ok bool) { + // top is the idx of the longest-prefix-match + if top, ok = n.Prefixes.IntersectionTop(&lpm.LookupTbl[idx]); ok { + return top, n.MustGetPrefix(top), true + } + return top, val, ok +} + +// Lookup is just a simple wrapper for LookupIdx. +func (n *FastNode[V]) Lookup(idx uint8) (val V, ok bool) { + _, val, ok = n.LookupIdx(idx) + return val, ok +} + +// CloneFlat returns a shallow copy of the current node, optionally performing deep copies of values. +// +// If cloneFn is nil, the stored values in prefixes are copied directly without modification. +// Otherwise, cloneFn is applied to each stored value for deep cloning. +// Child nodes are cloned shallowly: LeafNode and FringeNode children are cloned via their clone methods, +// but child nodes of type *FastNode[V] (subnodes) are assigned as-is without recursive cloning. +// This method does not recursively clone descendants beyond the immediate children. +// +// Note: The returned node is a new instance with copied slices but only shallow copies of nested nodes, +// except for LeafNode and FringeNode children which are cloned according to cloneFn. +func (n *FastNode[V]) CloneFlat(cloneFn func(V) V) *FastNode[V] { + if n == nil { + return nil + } + + c := new(FastNode[V]) + if n.IsEmpty() { + return c + } + + // copy ... + c.Prefixes = *(n.Prefixes.Copy()) + + // ... and clone the values + if cloneFn != nil { + for i, v := range c.Prefixes.Items { + c.Prefixes.Items[i] = cloneFn(v) + } + } + + // copy ... + c.childRankCache = n.childRankCache + c.Children = *(n.Children.Copy()) + + // Iterate over children to flat clone leaf/fringe nodes; + // for *FastNode[V] children, keep shallow references (no recursive clone) + for i, anyKid := range c.Children.Items { + switch kid := anyKid.(type) { + case *FastNode[V]: + // Shallow copy + case *LeafNode[V]: + // Clone leaf nodes, applying cloneFn as needed + c.Children.Items[i] = kid.CloneLeaf(cloneFn) + case *FringeNode[V]: + // Clone fringe nodes, applying cloneFn as needed + c.Children.Items[i] = kid.CloneFringe(cloneFn) + default: + panic("logic error, wrong node type") + } + } + + return c +} + +// CloneRec performs a recursive deep copy of the node and all its descendants. +// +// If cloneFn is nil, the stored values are copied directly without modification. +// Otherwise cloneFn is applied to each stored value for deep cloning. +// +// This method first creates a shallow clone of the current node using CloneFlat, +// applying cloneFn to values as described there. Then it recursively clones all +// child nodes of type *FastNode[V], performing a full deep clone down the subtree. +// +// Child nodes of type *LeafNode[V] and *FringeNode[V] are already cloned +// by CloneFlat. +// +// Returns a new instance of FastNode[V] which is a complete deep clone of the +// receiver node with all descendants. +func (n *FastNode[V]) CloneRec(cloneFn func(V) V) *FastNode[V] { + if n == nil { + return nil + } + + // Perform a flat clone of the current node. + c := n.CloneFlat(cloneFn) + + // Recursively clone all child nodes of type *FastNode[V] + for i, kidAny := range c.Children.Items { + if kid, ok := kidAny.(*FastNode[V]); ok { + c.Children.Items[i] = kid.CloneRec(cloneFn) + } + } + + return c +} diff --git a/vendor/github.com/gaissmai/bart/internal/nodes/fastmethodsgenerated.go b/vendor/github.com/gaissmai/bart/internal/nodes/fastmethodsgenerated.go new file mode 100644 index 0000000..fdd0fde --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/nodes/fastmethodsgenerated.go @@ -0,0 +1,2427 @@ +// Code generated from file "commonmethods_tmpl.go"; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package nodes + +import ( + "fmt" + "io" + "net/netip" + "slices" + "strings" + + "github.com/gaissmai/bart/internal/allot" + "github.com/gaissmai/bart/internal/art" + "github.com/gaissmai/bart/internal/value" +) + +// Insert adds or updates a network prefix and its associated value in the trie. +// Traversal begins at the specified byte depth. +// +// The trie utilizes path compression to conserve memory. A prefix is inserted: +// - Uncompressed into a node's prefix table at depth == strideCount. +// - As a path-compressed FringeNode if it qualifies as fringe [IsFringe]. +// - As a path-compressed LeafNode otherwise. +// +// When a new prefix collides with an existing compressed node (Leaf or Fringe), +// Insert resolves the collision by creating a new intermediate node, pushing +// the existing entry down to the next level, and continuing traversal. +// +// Parameters: +// - pfx: The network prefix to insert (must be in canonical/masked form). +// - val: The value to associate with the prefix. +// - depth: The current depth in the trie (0-based byte index). +// +// Returns true if an existing prefix was updated, false if a new insertion occurred. +func (n *FastNode[V]) Insert(pfx netip.Prefix, val V, depth int) (exists bool) { + ip := pfx.Addr() // the pfx must be in canonical form + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the prefix's octets. Each depth corresponds to an 8-bit stride. + // We descend through the trie until we either reach the final stride (depth == strideCount) + // or find an empty child slot where we can path-compress the remaining strides. + for ; depth < len(octets); depth++ { + octet := octets[depth] + + // The current depth matches the prefix's stride count, meaning this is the final + // node for this prefix. We insert it directly into this node's prefix table. + if depth == strideCount { + return n.InsertPrefix(art.PfxToIdx(octet, modBits), val) + } + + // No child exists at this octet path. Instead of creating intermediate nodes + // for the remaining strides, we path-compress the rest of the prefix into a single child slot. + if !n.Children.Test(octet) { + // If the prefix is perfectly aligned with the next stride boundary (e.g., /16 at depth 1), + // it acts as a default route for everything below it. We store it as a FringeNode. + // Otherwise, it has trailing bits or crosses boundaries, so we store it as a LeafNode. + if IsFringe(depth, pfxLen) { + return n.InsertChild(octet, NewFringeNode(val)) + } + return n.InsertChild(octet, NewLeafNode(pfx, val)) + } + + // A child already exists at this octet path. Retrieve it to either continue + // our descent along the strides or resolve a structural collision with a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *FastNode[V]: + // Standard intermediate node: descend to the next trie level. + n = kid + + case *LeafNode[V]: + // Collision with an existing path-compressed LeafNode. + // If it's the exact same prefix, simply update the value. + if kid.Prefix == pfx { + kid.Value = val + return true + } + + // Collision resolution: the paths diverge. + // 1. Create a new intermediate node. + // 2. Push the existing leaf down into this new node. + // 3. Replace the current child slot with the new node. + // 4. Descend into the new node to continue inserting 'pfx'. + newNode := new(FastNode[V]) + newNode.Insert(kid.Prefix, kid.Value, depth+1) + + n.InsertChild(octet, newNode) + n = newNode + + case *FringeNode[V]: + // Collision with an existing path-compressed FringeNode. + // If the incoming prefix is also a fringe at this depth, update the value. + if IsFringe(depth, pfxLen) { + kid.Value = val + return true + } + + // Collision resolution: + // The existing FringeNode acts as a catch-all (default route) for this sub-trie. + // To allow the incoming prefix to branch further, we expand the FringeNode + // into a full intermediate node and place its value at the default route index (1). + newNode := new(FastNode[V]) + newNode.InsertPrefix(1, kid.Value) + + n.InsertChild(octet, newNode) + n = newNode + + default: + panic("logic error, wrong node type") + } + } + panic("unreachable") +} + +// InsertPersist adds or updates a network prefix and its associated value in the trie +// using Copy-On-Write (COW) semantics. Traversal begins at the specified byte depth. +// +// Unlike [Insert], InsertPersist ensures structural integrity of the existing tree +// by cloning internal nodes along the descent path (Copy-On-Write) before mutation. +// +// Parameters: +// - cloneFn: The function used to clone values (V). +// - pfx: The network prefix to insert (must be in canonical/masked form). +// - val: The value to associate with the prefix. +// - depth: The current depth in the trie (0-based byte index). +// +// Returns true if an existing prefix was updated, false if a new insertion occurred. +func (n *FastNode[V]) InsertPersist(cloneFn func(V) V, pfx netip.Prefix, val V, depth int) (exists bool) { + ip := pfx.Addr() // the pfx must be in canonical form + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the prefix's octets. Each depth corresponds to an 8-bit stride. + // We descend through the trie until we either reach the final stride (depth == strideCount) + // or find an empty child slot where we can path-compress the remaining strides. + for ; depth < len(octets); depth++ { + octet := octets[depth] + + // The current depth matches the prefix's stride count, meaning this is the final + // node for this prefix. We insert it directly into this node's prefix table. + if depth == strideCount { + return n.InsertPrefix(art.PfxToIdx(octet, modBits), val) + } + + // No child exists at this octet path. Instead of creating intermediate nodes + // for the remaining strides, we path-compress the rest of the prefix into a single child slot. + if !n.Children.Test(octet) { + // If the prefix is perfectly aligned with the next stride boundary (e.g., /16 at depth 1), + // it acts as a default route for everything below it. We store it as a FringeNode. + // Otherwise, it has trailing bits or crosses boundaries, so we store it as a LeafNode. + if IsFringe(depth, pfxLen) { + return n.InsertChild(octet, NewFringeNode(val)) + } + return n.InsertChild(octet, NewLeafNode(pfx, val)) + } + + // A child already exists at this octet path. Retrieve it to either continue + // our descent along the strides or resolve a structural collision with a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *FastNode[V]: + // Standard intermediate node: Clone the traversed path to maintain persistence (COW). + // We clone the child node before modifying it, then replace the current child slot. + kid = kid.CloneFlat(cloneFn) + n.InsertChild(octet, kid) + n = kid + + case *LeafNode[V]: + // Collision with an existing path-compressed LeafNode. + // If it's the exact same prefix, simply update the value. + if kid.Prefix == pfx { + kid.Value = val + return true + } + + // Collision resolution: the paths diverge. + // 1. Create a new intermediate node. + // 2. Push the existing leaf down into this new node. + // 3. Replace the current child slot with the new node. + // 4. Descend into the new node to continue inserting 'pfx'. + newNode := new(FastNode[V]) + newNode.Insert(kid.Prefix, kid.Value, depth+1) + + n.InsertChild(octet, newNode) + n = newNode + + case *FringeNode[V]: + // Collision with an existing path-compressed FringeNode. + // If the incoming prefix is also a fringe at this depth, update the value. + if IsFringe(depth, pfxLen) { + kid.Value = val + return true + } + + // Collision resolution: + // The existing FringeNode acts as a catch-all (default route) for this sub-trie. + // To allow the incoming prefix to branch further, we expand the FringeNode + // into a full intermediate node and place its value at the default route index (1). + newNode := new(FastNode[V]) + newNode.InsertPrefix(1, kid.Value) + + n.InsertChild(octet, newNode) + n = newNode + + default: + panic("logic error, wrong node type") + } + } + panic("unreachable") +} + +// PurgeAndCompress performs bottom-up trie maintenance to restore path compression +// after a deletion. It unwinds the provided stack of parent nodes, identifying +// nodes that have become sparse (i.e., containing only a single prefix or a single +// child node) and prunes them by promoting the underlying entries to the parent level. +// +// This ensures the trie remains memory-efficient by collapsing redundant intermediate +// nodes back into path-compressed LeafNodes or FringeNodes whenever possible. +// +// Parameters: +// - stack: Array of parent nodes to process during bottom-up unwinding. +// - octets: The full path of octets leading to the current node. +// - is4: True for IPv4 processing, false for IPv6. +func (n *FastNode[V]) PurgeAndCompress(stack []*FastNode[V], octets []uint8, is4 bool) { + // Iterate backwards through the ancestor stack to prune nodes from the bottom up. + for depth := len(stack) - 1; depth >= 0; depth-- { + parent := stack[depth] + octet := octets[depth] + + // Check if the current node is redundant. + // A node may be redundant if it contains exactly one entry (either a prefix or + // a compressed child node). + pfxCount := n.PrefixCount() + childCount := n.ChildCount() + + // If it contains more than one entry, it is always structurally significant and cannot be pruned. + if pfxCount+childCount > 1 { + return + } + + switch { + case childCount == 1: + // The node has exactly one child. We determine if it is a path node, + // a compressed LeafNode, or a compressed FringeNode. + singleAddr, _ := n.Children.FirstSet() + anyKid := n.MustGetChild(singleAddr) + + switch kid := anyKid.(type) { + case *FastNode[V]: + // The child is an intermediate path node; the tree structure is required + // at this level. Compression cannot proceed further up. + return + case *LeafNode[V]: + // The child is a compressed LeafNode. Prune the current node + // and re-insert the leaf into the parent to elevate it. + parent.DeleteChild(octet) + parent.Insert(kid.Prefix, kid.Value, depth) + case *FringeNode[V]: + // The child is a compressed FringeNode. Prune the current node + // and re-insert the fringe as a leaf into the parent. + parent.DeleteChild(octet) + + // Reconstruct the full prefix for the fringe, as path compression + // requires the entire CIDR path, not just the remainder. + // depth is the parent's depth, so we offset by 1 for the kid's position. + fringePfx := CidrForFringe(octets, depth+1, is4, singleAddr) + + parent.Insert(fringePfx, kid.Value, depth) + } + + case pfxCount == 1: + // The node has exactly one prefix. Prune the node and elevate the + // prefix to the parent level as a leaf/fringe. + parent.DeleteChild(octet) + + // Retrieve the single prefix stored in this node. + idx, _ := n.Prefixes.FirstSet() + val := n.MustGetPrefix(idx) + + // Reconstruct the prefix from the path for re-insertion. + path := StridePath{} + copy(path[:], octets) + pfx := CidrFromPath(path, depth+1, is4, idx) + + parent.Insert(pfx, val, depth) + default: + panic("unreachable") + } + + // Move up to the next parent in the stack to continue pruning. + n = parent + } +} + +// Delete removes the prefix from the trie rooted at n and returns true if the +// prefix existed, false if it was not found. The prefix must be in canonical +// (masked) form. +// +// The trie uses path compression, so a prefix may be stored in one of three ways: +// - In the current node's prefix table when the prefix length aligns exactly +// with the stride boundary at this depth (depth == strideCount). +// - As a path-compressed FringeNode in a child slot for stride-aligned prefixes +// (e.g. /8, /16, /24); occurs at depth == strideCount-1. +// - As a path-compressed LeafNode in a child slot for prefixes otherwise. +// +// After a successful deletion, PurgeAndCompress walks the ancestor stack to prune +// now-empty nodes and restore path compression upward. +func (n *FastNode[V]) Delete(pfx netip.Prefix) (exists bool) { + ip := pfx.Addr() // pfx must be in canonical (masked) form + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Record ancestor nodes as we descend; PurgeAndCompress uses this stack to + // walk back up and clean up empty or re-compressible nodes after deletion. + stack := [MaxTreeDepth]*FastNode[V]{} + + for depth, octet := range octets { + depth &= DepthMask // BCE hint; keep Delete on the fast path + + stack[depth] = n // record current node before descending + + // At the stride boundary, the prefix is stored directly in this node's + // prefix table. + if depth == strideCount { + if exists = n.DeletePrefix(art.PfxToIdx(octet, modBits)); !exists { + return false + } + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + } + + // no child node exists at this octet; the prefix is not in the trie + if !n.Children.Test(octet) { + return false + } + + // A child node exists at this octet path, retrieve it. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *FastNode[V]: + n = kid // descend to the next trie level + + case *FringeNode[V]: + // A FringeNode holds a single stride-aligned prefix (/8, /16, ...). + // If pfx does not qualify as a fringe at this depth, it cannot be here. + if !IsFringe(depth, pfxLen) { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + case *LeafNode[V]: + // A LeafNode holds exactly one path-compressed prefix. + // Compare using the canonical (masked) form for an exact match. + if kid.Prefix != pfx { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// DeletePersist removes the prefix from the trie rooted at n using Copy-On-Write (COW) semantics. +// It returns true if the prefix existed, false if it was not found. The prefix must be in +// canonical (masked) form. +// +// Like [Delete], this method uses path compression. However, DeletePersist ensures +// the structural integrity of the existing tree by cloning internal nodes along the +// descent path (COW) before mutation. +// +// After a successful deletion, PurgeAndCompress walks the ancestor stack to prune +// now-empty nodes and restore path compression upward. +func (n *FastNode[V]) DeletePersist(cloneFn func(V) V, pfx netip.Prefix) (exists bool) { + ip := pfx.Addr() // pfx must be in canonical (masked) form + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Record ancestor nodes as we descend; PurgeAndCompress uses this stack to + // walk back up and clean up empty or re-compressible nodes after deletion. + // Since this is a COW operation, we store the cloned nodes here. + stack := [MaxTreeDepth]*FastNode[V]{} + + for depth, octet := range octets { + depth &= DepthMask // BCE hint; keep DeletePersist on the fast path + stack[depth] = n // record current node before descending + + // At the stride boundary, the prefix is stored directly in this node's + // prefix table. + if depth == strideCount { + if exists = n.DeletePrefix(art.PfxToIdx(octet, modBits)); !exists { + return false + } + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + } + + // no child node exists at this octet; the prefix is not in the trie + if !n.Children.Test(octet) { + return false + } + + // A child node exists at this octet path, retrieve it to either continue + // our descent or perform a persistent delete on a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *FastNode[V]: + // Standard intermediate node: Clone the traversed path to maintain + // persistence (COW). We clone the child node before modifying it, + // then replace the current child slot. + kid = kid.CloneFlat(cloneFn) + n.InsertChild(octet, kid) + n = kid + continue + + case *FringeNode[V]: + // A FringeNode holds a single stride-aligned prefix (/8, /16, ...). + // If pfx does not qualify as a fringe at this depth, it cannot be here. + if !IsFringe(depth, pfxLen) { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + case *LeafNode[V]: + // A LeafNode holds exactly one path-compressed prefix. + // Compare using the canonical (masked) form for an exact match. + if kid.Prefix != pfx { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// Get retrieves the value associated with the given network prefix. +// Traversal descends through the trie using the prefix's octets. +// +// The lookup handles path compression transparently: +// - If the path matches an internal node at the target stride, the value is retrieved +// from the node's prefix table. +// - If the path leads to a compressed LeafNode or FringeNode, the function verifies +// the prefix match before returning the value. +// +// Parameters: +// - pfx: The network prefix to look up (must be in canonical form). +// +// Returns: +// - val: The value associated with the prefix (zero value if not found). +// - exists: True if the prefix was found, false otherwise. +func (n *FastNode[V]) Get(pfx netip.Prefix) (val V, exists bool) { + // The prefix must be provided in canonical (masked) form for correct trie traversal. + ip := pfx.Addr() + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the trie octet by octet based on the prefix path. + for depth, octet := range octets { + // At the target stride boundary, the prefix is expected in this node's + // prefix table. + if depth == strideCount { + return n.GetPrefix(art.PfxToIdx(octet, modBits)) + } + + // If no child exists at this path, the prefix is not in the trie. + kidAny, ok := n.GetChild(octet) + if !ok { + return val, false + } + + // Identify the node type at this path segment. + switch kid := kidAny.(type) { + case *FastNode[V]: + // Standard intermediate node: descend to the next level. + n = kid + + case *FringeNode[V]: + // Reached a path-compressed FringeNode. + // Verify if the prefix qualifies as a fringe at this depth to return a match. + if IsFringe(depth, pfxLen) { + return kid.Value, true + } + return val, false + + case *LeafNode[V]: + // Reached a path-compressed LeafNode. + // Check if the stored prefix matches the lookup prefix exactly. + if kid.Prefix == pfx { + return kid.Value, true + } + return val, false + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// Modify performs an in-place modification of a prefix using the provided callback function. +// The callback receives the current value (if found) and existence flag, and returns +// a new value and deletion flag. +// +// Modify returns the size delta (-1, 0, +1). +// This method handles path traversal, node creation for new paths, and automatic +// purge/compress operations after deletions. +// +// Parameters: +// - pfx: The network prefix to modify (must be in canonical form) +// - cb: Callback function that receives (currentValue, exists) and returns (newValue, deleteFlag) +// +// Returns: +// - delta: Size change (-1 for delete, 0 for update/noop, +1 for insert) +func (n *FastNode[V]) Modify(pfx netip.Prefix, cb func(val V, found bool) (_ V, del bool)) (delta int) { + var zero V + + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // record the nodes on the path to the deleted node, needed to purge + // and/or path compress nodes after the deletion of a prefix + stack := [MaxTreeDepth]*FastNode[V]{} + + // find the proper trie node to update prefix + for depth, octet := range octets { + depth &= DepthMask // BCE + + // push current node on stack for path recording + stack[depth] = n + + // The current depth matches the prefix's stride count, meaning this is the final + // stride for this prefix. Insert or update it directly in this node's prefix table. + if depth == strideCount { + idx := art.PfxToIdx(octet, modBits) + + oldVal, existed := n.GetPrefix(idx) + newVal, del := cb(oldVal, existed) + + // update size if necessary + switch { + case !existed && del: // no-op + return 0 + + case existed && del: // delete + n.DeletePrefix(idx) + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return -1 + + case !existed: // insert + n.InsertPrefix(idx, newVal) + return 1 + + case existed: // update + n.InsertPrefix(idx, newVal) + return 0 + + default: + panic("unreachable") + } + + } + + // go down in tight loop to last octet + if !n.Children.Test(octet) { + // insert prefix path compressed + + newVal, del := cb(zero, false) + if del { + return 0 + } + + // insert + if IsFringe(depth, pfxLen) { + n.InsertChild(octet, NewFringeNode(newVal)) + } else { + n.InsertChild(octet, NewLeafNode(pfx, newVal)) + } + + return 1 + } + + // n.children.Test(octet) == true + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *FastNode[V]: + n = kid // descend down to next trie level + continue + + case *LeafNode[V]: + oldVal := kid.Value + + // update existing value if prefixes are equal + if kid.Prefix == pfx { + newVal, del := cb(oldVal, true) + + if !del { + kid.Value = newVal + return 0 + } + + // delete + n.DeleteChild(octet) + + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + + return -1 + } + + // stop if this is a no-op for zero values + newVal, del := cb(zero, false) + if del { + return 0 + } + + // create new node + // insert new child at current leaf position (octet) + newNode := new(FastNode[V]) + n.InsertChild(octet, newNode) + + // push the leaf down + // insert pfx with newVal in new node + newNode.Insert(kid.Prefix, kid.Value, depth+1) + newNode.Insert(pfx, newVal, depth+1) + + return 1 + + case *FringeNode[V]: + // update existing value if prefix is fringe + if IsFringe(depth, pfxLen) { + newVal, del := cb(kid.Value, true) + if !del { + kid.Value = newVal + return 0 + } + + // delete + n.DeleteChild(octet) + + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + + return -1 + } + + // stop if this is a no-op for zero values + newVal, del := cb(zero, false) + if del { + return 0 + } + + // create new node + // insert new child at current leaf position (octet) + newNode := new(FastNode[V]) + n.InsertChild(octet, newNode) + + // push the fringe down, it becomes a default route (idx=1) + // insert pfx with newVal in new node + newNode.InsertPrefix(1, kid.Value) + newNode.Insert(pfx, newVal, depth+1) + + return 1 + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// EqualRec performs recursive structural equality comparison between two nodes. +// Compares prefix and child bitsets, then recursively compares all stored values +// and child nodes. Returns true if the nodes and their entire subtrees are +// structurally and semantically identical, false otherwise. +// +// The comparison handles different node types (internal nodes, leafNodes, fringeNodes) +// and uses the equal function for value comparisons to support custom equality logic. +func (n *FastNode[V]) EqualRec(o *FastNode[V]) bool { + if n == nil || o == nil { + return n == o + } + if n == o { + return true + } + + if n.Prefixes.BitSet256 != o.Prefixes.BitSet256 { + return false + } + + if n.Children.BitSet256 != o.Children.BitSet256 { + return false + } + + for idx, nVal := range n.AllIndices() { + oVal := o.MustGetPrefix(idx) // mustGet is ok, bitsets are equal + if !value.Equal(nVal, oVal) { + return false + } + } + + for addr, nKid := range n.AllChildren() { + oKid := o.MustGetChild(addr) // mustGet is ok, bitsets are equal + + switch nKid := nKid.(type) { + case *FastNode[V]: + // oKid must also be a node + oKid, ok := oKid.(*FastNode[V]) + if !ok { + return false + } + + // compare rec-descent + if !nKid.EqualRec(oKid) { + return false + } + + case *LeafNode[V]: + // oKid must also be a leaf + oKid, ok := oKid.(*LeafNode[V]) + if !ok { + return false + } + + // compare prefixes + if nKid.Prefix != oKid.Prefix { + return false + } + + // compare values + if !value.Equal(nKid.Value, oKid.Value) { + return false + } + + case *FringeNode[V]: + // oKid must also be a fringe + oKid, ok := oKid.(*FringeNode[V]) + if !ok { + return false + } + + // compare values + if !value.Equal(nKid.Value, oKid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// DumpRec recursively descends the trie rooted at n and writes a human-readable +// representation of each visited node to w. +// +// It returns immediately if n is nil or empty. For each visited internal node +// it calls dump to write the node's representation, then iterates its child +// addresses and recurses into children of type *FastNode[V] (internal subnodes). +// The path slice and depth together represent the byte-wise path +// from the root to the current node; depth is incremented for each recursion. +// The is4 flag controls IPv4/IPv6 formatting used by dump. +func (n *FastNode[V]) DumpRec(w io.Writer, path StridePath, depth int, is4 bool) { + if n == nil || n.IsEmpty() { + return + } + + // dump this node + n.dump(w, path, depth, is4) + + // node may have children, rec-descent down + for addr, child := range n.AllChildren() { + if kid, ok := child.(*FastNode[V]); ok { + path[depth] = addr + kid.DumpRec(w, path, depth+1, is4) + } + } +} + +// dump writes a human-readable representation of the node to `w`. +// It prints the node type, depth, formatted path (IPv4 vs IPv6 controlled by `is4`), +// and bit count, followed by any stored prefixes (and their values when applicable), +// the set of child octets, and any path-compressed leaves or fringe entries. +func (n *FastNode[V]) dump(w io.Writer, path StridePath, depth int, is4 bool) { + bits := depth * strideLen + indent := strings.Repeat(".", depth) + + // printing values if V is not the empty struct{} + printValues := !value.IsEmptyStruct[V]() + + // node type with depth and octet path and bits. + fmt.Fprintf(w, "\n%s[%s] depth: %d path: [%s] / %d\n", + indent, n.hasType(), depth, ipStridePath(path, depth, is4), bits) + + if nPfxCount := n.PrefixCount(); nPfxCount != 0 { + var buf [256]uint8 + allIndices := n.Prefixes.AsSlice(&buf) + + // print the baseIndices for this node. + fmt.Fprintf(w, "%sindexs(#%d): %v\n", indent, nPfxCount, allIndices) + + // print the prefixes for this node + fmt.Fprintf(w, "%sprefxs(#%d):", indent, nPfxCount) + + for _, idx := range allIndices { + pfx := CidrFromPath(path, depth, is4, idx) + fmt.Fprintf(w, " %s", pfx) + } + + fmt.Fprintln(w) + + // skip printing values if V is zero-sized + if printValues { + + // print the values for this node + fmt.Fprintf(w, "%svalues(#%d):", indent, nPfxCount) + + for _, idx := range allIndices { + val := n.MustGetPrefix(idx) + fmt.Fprintf(w, " %#v", val) + } + + fmt.Fprintln(w) + } + } + + if cc := n.ChildCount(); cc != 0 { + allAddrs := make([]uint8, 0, cc) + childAddrs := make([]uint8, 0, cc) + leafAddrs := make([]uint8, 0, cc) + fringeAddrs := make([]uint8, 0, cc) + + // the node has recursive child nodes or path-compressed leaves + for addr, child := range n.AllChildren() { + allAddrs = append(allAddrs, addr) + + switch child.(type) { + case *FastNode[V]: + childAddrs = append(childAddrs, addr) + continue + + case *FringeNode[V]: + fringeAddrs = append(fringeAddrs, addr) + + case *LeafNode[V]: + leafAddrs = append(leafAddrs, addr) + + default: + panic("logic error, wrong node type") + } + } + + // print the children for this node. + fmt.Fprintf(w, "%soctets(#%d): %v\n", indent, len(allAddrs), allAddrs) + + if leafCount := len(leafAddrs); leafCount > 0 { + // print the pathcomp prefixes for this node + fmt.Fprintf(w, "%sleaves(#%d):", indent, leafCount) + + for _, addr := range leafAddrs { + kid := n.MustGetChild(addr).(*LeafNode[V]) + + // skip printing values if V is zero-sized + if printValues { + fmt.Fprintf(w, " %s:{%s, %v}", addrFmt(addr, is4), kid.Prefix, kid.Value) + } else { + fmt.Fprintf(w, " %s:{%s}", addrFmt(addr, is4), kid.Prefix) + } + } + + fmt.Fprintln(w) + } + + if fringeCount := len(fringeAddrs); fringeCount > 0 { + // print the pathcomp prefixes for this node + fmt.Fprintf(w, "%sfringe(#%d):", indent, fringeCount) + + for _, addr := range fringeAddrs { + fringePfx := CidrForFringe(path[:], depth, is4, addr) + + kid := n.MustGetChild(addr).(*FringeNode[V]) + + // skip printing values if V is zero-sized + if printValues { + fmt.Fprintf(w, " %s:{%s, %v}", addrFmt(addr, is4), fringePfx, kid.Value) + } else { + fmt.Fprintf(w, " %s:{%s}", addrFmt(addr, is4), fringePfx) + } + } + + fmt.Fprintln(w) + } + + if childCount := len(childAddrs); childCount > 0 { + // print the next child + fmt.Fprintf(w, "%schilds(#%d):", indent, childCount) + + for _, addr := range childAddrs { + fmt.Fprintf(w, " %s", addrFmt(addr, is4)) + } + + fmt.Fprintln(w) + } + + } +} + +// DumpString traverses the trie to the node at the specified depth along the given +// octet path and returns its string representation via Dump. +// +// If the path is invalid or encounters an unexpected node type during traversal, +// it returns an error message string instead. +// +// Parameters: +// - octets: The path of octets to follow from the root +// - depth: Target depth to reach before dumping (0-based byte index) +// - is4: True for IPv4 formatting, false for IPv6 +// +// Returns a formatted string representation of the target node or an error message. +func (n *FastNode[V]) DumpString(octets []uint8, depth int, is4 bool) string { + path := StridePath{} + copy(path[:], octets) + + buf := new(strings.Builder) + for i := range depth { + anyKid, ok := n.GetChild(path[i]) + if !ok { + return fmt.Sprintf("ERROR: kid for %v[%d] is NOT set in node\n", octets, i) + } + + kid, ok := anyKid.(*FastNode[V]) + if !ok { + return fmt.Sprintf("ERROR: kid for %v[%d] is NO %s\n", octets, i, "FastNode[V]") + } + + // traverse + n = kid + } + + n.dump(buf, path, depth, is4) + return buf.String() +} + +// hasType classifies the given node into one of the nodeType values. +// +// It inspects immediate statistics (prefix count, child count, node, leaf and +// fringe counts) for the node and returns: +// - nullNode: no prefixes and no children +// - stopNode: has children but no subnodes (nodes == 0) +// - halfNode: contains at least one leaf or fringe and also has subnodes, but +// no prefixes +// - fullNode: has prefixes and also has subnodes +// - pathNode: has subnodes only (no prefixes, leaves, or fringes) +// +// The order of these checks is significant to ensure the correct classification. +func (n *FastNode[V]) hasType() nodeType { + s := n.Stats() + + // the order is important + switch { + case s.Prefixes == 0 && s.Children == 0: + return nullNode + case s.SubNodes == 0: + return stopNode + case (s.Leaves > 0 || s.Fringes > 0) && s.SubNodes > 0 && s.Prefixes == 0: + return halfNode + case (s.Prefixes > 0 || s.Leaves > 0 || s.Fringes > 0) && s.SubNodes > 0: + return fullNode + case (s.Prefixes == 0 && s.Leaves == 0 && s.Fringes == 0) && s.SubNodes > 0: + return pathNode + default: + panic(fmt.Sprintf("UNREACHABLE: pfx: %d, chld: %d, node: %d, leaf: %d, fringe: %d", + s.Prefixes, s.Children, s.SubNodes, s.Leaves, s.Fringes)) + } +} + +// Stats returns immediate statistics for n: counts of prefixes and children, +// and a classification of each child into nodes, leaves, or fringes. +// It inspects only the direct children of n (not the whole subtree). +// Panics if a child has an unexpected concrete type. +func (n *FastNode[V]) Stats() (s StatsT) { + s.Prefixes = n.PrefixCount() + s.Children = n.ChildCount() + + for _, child := range n.AllChildren() { + switch child.(type) { + case *FastNode[V]: + s.SubNodes++ + + case *FringeNode[V]: + s.Fringes++ + + case *LeafNode[V]: + s.Leaves++ + + default: + panic("logic error, wrong node type") + } + } + + return s +} + +// StatsRec returns aggregated statistics for the subtree rooted at n. +// +// It walks the node tree recursively and sums immediate counts (prefixes and +// child slots) plus the number of nodes, leaves, and fringe nodes in the +// subtree. If n is nil or empty, a zeroed stats is returned. The returned +// SubNodes count includes the current node. The function will panic if a child +// has an unexpected concrete type. +func (n *FastNode[V]) StatsRec() (s StatsT) { + if n == nil || n.IsEmpty() { + return s + } + + s.Prefixes = n.PrefixCount() + s.Children = n.ChildCount() + s.SubNodes = 1 // this node + s.Leaves = 0 + s.Fringes = 0 + + for _, child := range n.AllChildren() { + switch kid := child.(type) { + case *FastNode[V]: + // rec-descent + rs := kid.StatsRec() + + s.Prefixes += rs.Prefixes + s.Children += rs.Children + s.SubNodes += rs.SubNodes + s.Leaves += rs.Leaves + s.Fringes += rs.Fringes + + case *FringeNode[V]: + s.Fringes++ + + case *LeafNode[V]: + s.Leaves++ + + default: + panic("logic error, wrong node type") + } + } + + return s +} + +// FprintRec recursively prints a hierarchical CIDR tree representation +// starting from this node to the provided writer. The output shows the +// routing table structure in human-readable format for debugging and analysis. +func (n *FastNode[V]) FprintRec(w io.Writer, parent TrieItem[V], pad string) error { + // recursion stop condition + if n == nil || n.IsEmpty() { + return nil + } + + // get direct covered childs for this parent ... + directItems := n.DirectItemsRec(parent.Idx, parent.Path, parent.Depth, parent.Is4) + + // sort them by netip.Prefix, not by baseIndex + slices.SortFunc(directItems, func(a, b TrieItem[V]) int { + return CmpPrefix(a.Cidr, b.Cidr) + }) + + // printing values if V is not the empty struct{} + printValues := !value.IsEmptyStruct[V]() + + // for all direct item under this node ... + for i, item := range directItems { + // symbols used in tree + glyph := "├─ " + space := "│ " + + // ... treat last kid special + if i == len(directItems)-1 { + glyph = "└─ " + space = " " + } + + var err error + // val is the empty struct, don't print it + if printValues { + _, err = fmt.Fprintf(w, "%s%s (%v)\n", pad+glyph, item.Cidr, item.Val) + } else { + // skip printing values if V is zero-sized + _, err = fmt.Fprintf(w, "%s%s\n", pad+glyph, item.Cidr) + } + + if err != nil { + return err + } + + // rec-descent with this item as parent + nextNode, _ := item.Node.(*FastNode[V]) + if err = nextNode.FprintRec(w, item, pad+space); err != nil { + return err + } + } + + return nil +} + +// DirectItemsRec, returns the direct covered items by parent. +// It's a complex recursive function, you have to know the data structure +// by heart to understand this function! +func (n *FastNode[V]) DirectItemsRec(parentIdx uint8, path StridePath, depth int, is4 bool) (directItems []TrieItem[V]) { + // recursion stop condition + if n == nil || n.IsEmpty() { + return nil + } + + // prefixes: + // for all idx's (prefixes mapped by baseIndex) in this node + // do a longest-prefix-match + for idx, val := range n.AllIndices() { + // tricky part, skip self + // test with next possible lpm (idx>>1), it's a complete binary tree + nextIdx := idx >> 1 + + // fast skip, lpm not possible + if nextIdx < parentIdx { + continue + } + + // do a longest-prefix-match + lpm, _, _ := n.LookupIdx(nextIdx) + + // be aware, 0 is here a possible value for parentIdx and lpm (if not found) + if lpm == parentIdx { + // prefix is directly covered by parent + + item := TrieItem[V]{ + Node: n, + Is4: is4, + Path: path, + Depth: depth, + Idx: idx, + // get the prefix back from trie + Cidr: CidrFromPath(path, depth, is4, idx), + Val: val, + } + + directItems = append(directItems, item) + } + } + + // children: + for addr, child := range n.AllChildren() { + hostIdx := art.OctetToIdx(addr) + + // do a longest-prefix-match + lpm, _, _ := n.LookupIdx(hostIdx) + + // be aware, 0 is here a possible value for parentIdx and lpm (if not found) + if lpm == parentIdx { + // child is directly covered by parent + switch kid := child.(type) { + case *FastNode[V]: // traverse rec-descent, call with next child node, + // next trie level, set parentIdx to 0, adjust path and depth + path[depth] = addr + directItems = append(directItems, kid.DirectItemsRec(0, path, depth+1, is4)...) + + case *LeafNode[V]: // path-compressed child, stops recursion for this child + item := TrieItem[V]{ + Node: nil, + Is4: is4, + Cidr: kid.Prefix, + Val: kid.Value, + } + directItems = append(directItems, item) + + case *FringeNode[V]: // path-compressed fringe, stops recursion for this child + item := TrieItem[V]{ + Node: nil, + Is4: is4, + // get the prefix back from trie + Cidr: CidrForFringe(path[:], depth, is4, addr), + Val: kid.Value, + } + directItems = append(directItems, item) + + default: + panic("logic error, wrong node type") + } + } + } + + return directItems +} + +// UnionRec recursively merges another node o into the receiver node n. +// +// All prefix and child entries from o are cloned and inserted into n. +// If a prefix already exists in n, its value is overwritten by the value from o, +// and the duplicate is counted in the return value. This count can later be used +// to update size-related metadata in the parent trie. +// +// The union handles all possible combinations of child node types (node, leaf, fringe) +// between the two nodes. Structural conflicts are resolved by creating new intermediate +// *FastNode[V] objects and pushing both children further down the trie. Leaves and fringes +// are also recursively relocated as needed to preserve prefix semantics. +// +// The merge operation is destructive on the receiver n, but leaves the source node o unchanged. +// +// Returns the number of duplicate prefixes that were overwritten during merging. +func (n *FastNode[V]) UnionRec(cloneFn func(V) V, o *FastNode[V], depth int) (duplicates int) { + if cloneFn == nil { + cloneFn = func(v V) V { return v } + } + + buf := [256]uint8{} + + // for all prefixes in other node do ... + for _, oIdx := range o.Prefixes.AsSlice(&buf) { + // clone/copy the value from other node at idx + val := o.MustGetPrefix(oIdx) + clonedVal := cloneFn(val) + + // insert/overwrite cloned value from o into n + if n.InsertPrefix(oIdx, clonedVal) { + // this prefix is duplicate in n and o + duplicates++ + } + } + + // for all child addrs in other node do ... + for _, addr := range o.Children.AsSlice(&buf) { + otherChild := o.MustGetChild(addr) + thisChild, thisExists := n.GetChild(addr) + + // Use helper function to handle all 4x3 combinations + duplicates += n.handleMatrix(cloneFn, thisExists, thisChild, otherChild, addr, depth) + } + + return duplicates +} + +// UnionRecPersist is similar to unionRec but performs an immutable union of nodes. +func (n *FastNode[V]) UnionRecPersist(cloneFn func(V) V, o *FastNode[V], depth int) (duplicates int) { + if cloneFn == nil { + cloneFn = func(v V) V { return v } + } + + buf := [256]uint8{} + + // for all prefixes in other node do ... + for _, oIdx := range o.Prefixes.AsSlice(&buf) { + // clone/copy the value from other node + val := o.MustGetPrefix(oIdx) + clonedVal := cloneFn(val) + + // insert/overwrite cloned value from o into n + if exists := n.InsertPrefix(oIdx, clonedVal); exists { + // this prefix is duplicate in n and o + duplicates++ + } + } + + // for all child addrs in other node do ... + for _, addr := range o.Children.AsSlice(&buf) { + otherChild := o.MustGetChild(addr) + thisChild, thisExists := n.GetChild(addr) + + // Use helper function to handle all 4x3 combinations + duplicates += n.handleMatrixPersist(cloneFn, thisExists, thisChild, otherChild, addr, depth) + } + + return duplicates +} + +// handleMatrix, 12 possible combinations to union this child and other child +// +// THIS, OTHER: (always clone the other kid!) +// -------------- +// NULL, node <-- insert node at addr +// NULL, leaf <-- insert leaf at addr +// NULL, fringe <-- insert fringe at addr +// +// node, node <-- union rec-descent with node +// node, leaf <-- insert leaf at depth+1 +// node, fringe <-- insert fringe at depth+1 +// +// leaf, node <-- insert new node, push this leaf down, union rec-descent +// leaf, leaf <-- insert new node, push both leaves down (!first check equality) +// leaf, fringe <-- insert new node, push this leaf and fringe down +// +// fringe, node <-- insert new node, push this fringe down, union rec-descent +// fringe, leaf <-- insert new node, push this fringe down, insert other leaf at depth+1 +// fringe, fringe <-- just overwrite value +func (n *FastNode[V]) handleMatrix(cloneFn func(V) V, thisExists bool, thisChild, otherChild any, addr uint8, depth int) int { + // Do ALL type assertions upfront - reduces line noise + var ( + thisNode, thisIsNode = thisChild.(*FastNode[V]) + thisLeaf, thisIsLeaf = thisChild.(*LeafNode[V]) + thisFringe, thisIsFringe = thisChild.(*FringeNode[V]) + + otherNode, otherIsNode = otherChild.(*FastNode[V]) + otherLeaf, otherIsLeaf = otherChild.(*LeafNode[V]) + otherFringe, otherIsFringe = otherChild.(*FringeNode[V]) + ) + + // just insert cloned child at this empty slot + if !thisExists { + switch { + case otherIsNode: + n.InsertChild(addr, otherNode.CloneRec(cloneFn)) + case otherIsLeaf: + n.InsertChild(addr, &LeafNode[V]{Prefix: otherLeaf.Prefix, Value: cloneFn(otherLeaf.Value)}) + case otherIsFringe: + n.InsertChild(addr, &FringeNode[V]{Value: cloneFn(otherFringe.Value)}) + default: + panic("logic error, wrong node type") + } + return 0 + } + + // Case 1: Special cases that DON'T need a new node + + // Special case: fringe + fringe -> just overwrite value + if thisIsFringe && otherIsFringe { + thisFringe.Value = cloneFn(otherFringe.Value) + return 1 + } + + // Special case: leaf + leaf with same prefix -> just overwrite value + if thisIsLeaf && otherIsLeaf && thisLeaf.Prefix == otherLeaf.Prefix { + thisLeaf.Value = cloneFn(otherLeaf.Value) + return 1 + } + + // Case 2: thisChild is already a node - insert into it, no new node needed + if thisIsNode { + switch { + case otherIsNode: + return thisNode.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if thisNode.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if thisNode.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong node type") + } + } + + // Case 3: All remaining cases need a new node + // (thisChild is leaf or fringe, and we didn't hit the special cases above) + + nc := new(FastNode[V]) + + // Push existing child down into new node + switch { + case thisIsLeaf: + nc.Insert(thisLeaf.Prefix, thisLeaf.Value, depth+1) + case thisIsFringe: + nc.InsertPrefix(1, thisFringe.Value) + default: + panic("logic error, unexpected this child type") + } + + // Replace child with new node + n.InsertChild(addr, nc) + + // Now handle other child + switch { + case otherIsNode: + return nc.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if nc.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if nc.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong other node type") + } +} + +// handleMatrixPersist, 12 possible combinations to union this child and other child +// +// THIS, OTHER: (always clone the other kid!) +// -------------- +// NULL, node <-- insert node at addr +// NULL, leaf <-- insert leaf at addr +// NULL, fringe <-- insert fringe at addr +// +// node, node <-- union rec-descent with node +// node, leaf <-- insert leaf at depth+1 +// node, fringe <-- insert fringe at depth+1 +// +// leaf, node <-- insert new node, push this leaf down, union rec-descent +// leaf, leaf <-- insert new node, push both leaves down (!first check equality) +// leaf, fringe <-- insert new node, push this leaf and fringe down +// +// fringe, node <-- insert new node, push this fringe down, union rec-descent +// fringe, leaf <-- insert new node, push this fringe down, insert other leaf at depth+1 +// fringe, fringe <-- just overwrite value +func (n *FastNode[V]) handleMatrixPersist(cloneFn func(V) V, thisExists bool, thisChild, otherChild any, addr uint8, depth int) int { + // Do ALL type assertions upfront - reduces line noise + var ( + thisNode, thisIsNode = thisChild.(*FastNode[V]) + thisLeaf, thisIsLeaf = thisChild.(*LeafNode[V]) + thisFringe, thisIsFringe = thisChild.(*FringeNode[V]) + + otherNode, otherIsNode = otherChild.(*FastNode[V]) + otherLeaf, otherIsLeaf = otherChild.(*LeafNode[V]) + otherFringe, otherIsFringe = otherChild.(*FringeNode[V]) + ) + + // just insert cloned child at this empty slot + if !thisExists { + switch { + case otherIsNode: + n.InsertChild(addr, otherNode.CloneRec(cloneFn)) + case otherIsLeaf: + n.InsertChild(addr, &LeafNode[V]{Prefix: otherLeaf.Prefix, Value: cloneFn(otherLeaf.Value)}) + case otherIsFringe: + n.InsertChild(addr, &FringeNode[V]{Value: cloneFn(otherFringe.Value)}) + default: + panic("logic error, wrong node type") + } + return 0 + } + + // Case 1: Special cases that DON'T need a new node + + // Special case: fringe + fringe -> just overwrite value + if thisIsFringe && otherIsFringe { + thisFringe.Value = cloneFn(otherFringe.Value) + return 1 + } + + // Special case: leaf + leaf with same prefix -> just overwrite value + if thisIsLeaf && otherIsLeaf && thisLeaf.Prefix == otherLeaf.Prefix { + thisLeaf.Value = cloneFn(otherLeaf.Value) + return 1 + } + + // Case 2: thisChild is already a node - clone this node, insert into it + if thisIsNode { + // CLONE the node + + // thisNode points now to cloned kid + thisNode = thisNode.CloneFlat(cloneFn) + + // replace kid with cloned thisKid + n.InsertChild(addr, thisNode) + + switch { + case otherIsNode: + return thisNode.UnionRecPersist(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if thisNode.InsertPersist(cloneFn, otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if thisNode.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong node type") + } + } + + // Case 3: All remaining cases need a new node + // (thisChild is leaf or fringe, and we didn't hit the special cases above) + + nc := new(FastNode[V]) + + // Push existing child down into new node + switch { + case thisIsLeaf: + nc.Insert(thisLeaf.Prefix, thisLeaf.Value, depth+1) + case thisIsFringe: + nc.InsertPrefix(1, thisFringe.Value) + default: + panic("logic error, unexpected this child type") + } + + // Replace child with new node + n.InsertChild(addr, nc) + + // Now handle other child + switch { + case otherIsNode: + return nc.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if nc.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if nc.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong other node type") + } +} + +// AllRec recursively traverses the trie starting at the current node, +// applying the provided yield function to every stored prefix and value. +// +// For each route entry (prefix and value), yield is invoked. If yield returns false, +// the traversal stops immediately, and false is propagated upwards, +// enabling early termination. +// +// The function handles all prefix entries in the current node, as well as any children - +// including sub-nodes, leaf nodes with full prefixes, and fringe nodes +// representing path-compressed prefixes. IP prefix reconstruction is performed on-the-fly +// from the current path and depth. +// +// The traversal order is not defined. This implementation favors simplicity +// and runtime efficiency over consistency of iteration sequence. +func (n *FastNode[V]) AllRec(path StridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { + var buf [256]uint8 + for _, idx := range n.Prefixes.AsSlice(&buf) { + cidr := CidrFromPath(path, depth, is4, idx) + val := n.MustGetPrefix(idx) + + // callback for this prefix and val + if !yield(cidr, val) { + // early exit + return false + } + } + + // for all children (nodes and leaves) in this node do ... + for _, addr := range n.Children.AsSlice(&buf) { + anyKid := n.MustGetChild(addr) + switch kid := anyKid.(type) { + case *FastNode[V]: + // rec-descent with this node + path[depth] = addr + if !kid.AllRec(path, depth+1, is4, yield) { + // early exit + return false + } + case *LeafNode[V]: + // callback for this leaf + if !yield(kid.Prefix, kid.Value) { + // early exit + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// AllRecSorted recursively traverses the trie in prefix-sorted order and applies +// the given yield function to each stored prefix and value. +// +// Unlike AllRec, this implementation ensures that route entries are visited in +// canonical prefix sort order. To achieve this, +// both the prefixes and children of the current node are gathered, sorted, +// and then interleaved during traversal based on logical octet positioning. +// +// The function first sorts relevant entries by their prefix index and address value, +// using a comparison function that ranks prefixes according to their mask length and position. +// Then it walks the trie, always yielding child entries that fall before the current prefix, +// followed by the prefix itself. Remaining children are processed once all prefixes have been visited. +// +// Prefixes are reconstructed on-the-fly from the traversal path, and iteration includes all child types: +// inner nodes (recursive descent), leaf nodes, and fringe (compressed) prefixes. +// +// The order is stable and predictable, making the function suitable for use cases +// like table exports, comparisons or serialization. +// +// Parameters: +// - path: the current traversal path through the trie +// - depth: current depth in the trie (0-based) +// - is4: true for IPv4 processing, false for IPv6 +// - yield: callback function invoked for each prefix/value pair +// +// Returns false if yield function requests early termination. +func (n *FastNode[V]) AllRecSorted(path StridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { + // get slice of all child octets, sorted by addr + var childBuf [256]uint8 + allChildAddrs := n.Children.AsSlice(&childBuf) + + // get slice of all indexes, sorted by idx + var idxBuf [256]uint8 + allIndices := n.Prefixes.AsSlice(&idxBuf) + + // sort indices in CIDR sort order + slices.SortFunc(allIndices, CmpIndexRank) + + childCursor := 0 + + // yield indices and children in CIDR sort order + for _, pfxIdx := range allIndices { + pfxOctet, _ := art.IdxToPfx(pfxIdx) + + // yield all children before idx + for j := childCursor; j < len(allChildAddrs); j++ { + childAddr := allChildAddrs[j] + + if childAddr >= pfxOctet { + break + } + + // yield the node (rec-descent) or leaf + anyKid := n.MustGetChild(childAddr) + switch kid := anyKid.(type) { + case *FastNode[V]: + path[depth] = childAddr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, childAddr) + if !yield(fringePfx, kid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + + childCursor++ + } + + // yield the prefix for this idx + cidr := CidrFromPath(path, depth, is4, pfxIdx) + // n.prefixes.Items[i] not possible after sorting allIndices + if !yield(cidr, n.MustGetPrefix(pfxIdx)) { + return false + } + } + + // yield the rest of leaves and nodes (rec-descent) + for j := childCursor; j < len(allChildAddrs); j++ { + addr := allChildAddrs[j] + anyKid := n.MustGetChild(addr) + switch kid := anyKid.(type) { + case *FastNode[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + if !yield(fringePfx, kid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// EachLookupPrefix performs a hierarchical lookup of all matching prefixes +// in the current node’s 8-bit stride-based prefix table. +// +// The function walks up the trie-internal complete binary tree (CBT), +// testing each possible prefix length mask (in decreasing order of specificity), +// and invokes the yield function for every matching entry. +// +// The given idx refers to the position for this stride's prefix and is used +// to derive a backtracking path through the CBT by repeatedly halving the index. +// At each step, if a prefix exists in the table, its corresponding CIDR is +// reconstructed and yielded. If yield returns false, traversal stops early. +// +// This function is intended for internal use during supernet traversal and +// does not descend the trie further. +func (n *FastNode[V]) EachLookupPrefix(ip netip.Addr, depth int, pfxIdx uint8, yield func(netip.Prefix, V) bool) (ok bool) { + for ; pfxIdx > 0; pfxIdx >>= 1 { + if n.Prefixes.Test(pfxIdx) { + val := n.MustGetPrefix(pfxIdx) + + // get the CIDR back + _, pfxLen := art.IdxToPfx(pfxIdx) + cidr, _ := ip.Prefix(depth<<3 + int(pfxLen)) + + if !yield(cidr, val) { + return false + } + } + } + + return true +} + +// EachSubnet yields all prefix entries and child nodes covered by a given parent prefix, +// sorted in natural CIDR order, within the current node. +// +// The function iterates through all prefixes and children from the node’s stride tables. +// Only entries that fall within the address range defined by the parent prefix index (pfxIdx) +// are included. Matching entries are buffered, sorted, and passed through to the yield function. +// +// Child entries (nodes, leaves, fringes) that fall under the covered address range +// are processed recursively via AllRecSorted to ensure sorted traversal. +// +// This function is intended for internal use by Subnets(), and it assumes the +// current node is positioned at the point in the trie corresponding to the parent prefix. +func (n *FastNode[V]) EachSubnet(octets []byte, depth int, is4 bool, pfxIdx uint8, yield func(netip.Prefix, V) bool) bool { + // octets as array, needed below more than once + var path StridePath + copy(path[:], octets) + + pfxFirstAddr, pfxLastAddr := art.IdxToRange(pfxIdx) + + allCoveredIndices := make([]uint8, 0, n.PrefixCount()) + + var buf [256]uint8 + for _, idx := range n.Prefixes.AsSlice(&buf) { + thisFirstAddr, thisLastAddr := art.IdxToRange(idx) + + if thisFirstAddr >= pfxFirstAddr && thisLastAddr <= pfxLastAddr { + allCoveredIndices = append(allCoveredIndices, idx) + } + } + + // sort indices in CIDR sort order + slices.SortFunc(allCoveredIndices, CmpIndexRank) + + // 2. collect all covered child addrs by prefix + + allCoveredChildAddrs := make([]uint8, 0, n.ChildCount()) + for _, addr := range n.Children.AsSlice(&buf) { + if addr >= pfxFirstAddr && addr <= pfxLastAddr { + allCoveredChildAddrs = append(allCoveredChildAddrs, addr) + } + } + + // 3. yield covered indices, path-compressed prefixes + // and children in CIDR sort order + + addrCursor := 0 + + // yield indices and children in CIDR sort order + for _, pfxIdx := range allCoveredIndices { + pfxOctet, _ := art.IdxToPfx(pfxIdx) + + // yield all children before idx + for j := addrCursor; j < len(allCoveredChildAddrs); j++ { + addr := allCoveredChildAddrs[j] + if addr >= pfxOctet { + break + } + + // yield the node or leaf? + switch kid := n.MustGetChild(addr).(type) { + case *FastNode[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + + addrCursor++ + } + + // yield the prefix for this idx + cidr := CidrFromPath(path, depth, is4, pfxIdx) + // n.prefixes.Items[i] not possible after sorting allIndices + if !yield(cidr, n.MustGetPrefix(pfxIdx)) { + return false + } + } + + // yield the rest of leaves and nodes (rec-descent) + for _, addr := range allCoveredChildAddrs[addrCursor:] { + // yield the node or leaf? + switch kid := n.MustGetChild(addr).(type) { + case *FastNode[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// Supernets yields all supernet prefixes of pfx that exist in the trie, +// in reverse order (most-specific first, least-specific last). +// +// It traverses upward from the given prefix toward the root, collecting +// matching prefixes along the path. The traversal uses a stack to yield +// results in reverse order, so that more-specific supernets appear before +// less-specific ones. +// +// The function handles all node types (internal nodes, leaves, and fringes) +// and stops early if the yield callback returns false. +// +// Parameters: +// - pfx: The prefix for which to find supernets +// - yield: Callback function invoked for each supernet prefix/value pair +// +// The yield function receives prefix/value pairs and returns false to stop +// the iteration early. +func (n *FastNode[V]) Supernets(pfx netip.Prefix, yield func(netip.Prefix, V) bool) { + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // stack of the traversed nodes for reverse ordering of supernets + stack := [MaxTreeDepth]*FastNode[V]{} + + // run variable, used after for loop + var depth int + var octet byte + + // find last node along this octet path +LOOP: + for depth, octet = range octets { + // stepped one past the last stride of interest; back up to last and exit + if depth > strideCount { + depth-- + break + } + // push current node on stack + stack[depth] = n + + // descend down the trie + if !n.Children.Test(octet) { + break LOOP + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *FastNode[V]: + n = kid + continue LOOP // descend down to next trie level + + case *LeafNode[V]: + if kid.Prefix.Bits() > pfx.Bits() { + break LOOP + } + + if kid.Prefix.Overlaps(pfx) { + if !yield(kid.Prefix, kid.Value) { + // early exit + return + } + } + // end of trie along this octets path + break LOOP + + case *FringeNode[V]: + fringePfx := CidrForFringe(octets, depth, is4, octet) + if fringePfx.Bits() > pfx.Bits() { + break LOOP + } + + if fringePfx.Overlaps(pfx) { + if !yield(fringePfx, kid.Value) { + // early exit + return + } + } + // end of trie along this octets path + break LOOP + + default: + panic("logic error, wrong node type") + } + } + + // start backtracking, unwind the stack + for ; depth >= 0; depth-- { + n = stack[depth] + + // only the lastOctet may have a different prefix len + // all others are just host routes + var idx uint8 + octet = octets[depth] + // Last “octet” from prefix + // Note: For /32 and /128, depth never reaches strideCount (4/16), + if depth == strideCount { + idx = art.PfxToIdx(octet, modBits) + } else { + idx = art.OctetToIdx(octet) + } + + // micro benchmarking, skip if there is no match + if !n.Contains(idx) { + continue + } + + // yield all the matching prefixes, not just the lpm + if !n.EachLookupPrefix(ip, depth, idx, yield) { + // early exit + return + } + } +} + +// Subnets yields all subnet prefixes covered by pfx that exist in the trie, +// in CIDR sort order. +// +// It first locates the trie node corresponding to pfx, then recursively +// yields all prefixes and child entries contained within that subtree. +// The traversal uses sorted iteration to maintain canonical CIDR ordering. +// +// The function handles various node types (internal nodes, leaves, and fringes) +// and uses EachSubnet and AllRecSorted for sorted traversal of covered prefixes. +// +// Parameters: +// - pfx: The parent prefix whose subnets should be yielded +// - yield: Callback function invoked for each subnet prefix/value pair +// +// The yield function receives prefix/value pairs and returns false to stop +// the iteration early. If pfx doesn't exist in the trie, no prefixes are yielded. +func (n *FastNode[V]) Subnets(pfx netip.Prefix, yield func(netip.Prefix, V) bool) { + // values derived from pfx + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // find the trie node + for depth, octet := range octets { + // Last “octet” from prefix + // Note: For /32 and /128, depth never reaches strideCount (4/16), + // so those are handled below via the fringe/leaf path. + if depth == strideCount { + idx := art.PfxToIdx(octet, modBits) + n.EachSubnet(octets, depth, is4, idx, yield) + return + } + + if !n.Children.Test(octet) { + return + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *FastNode[V]: + n = kid + continue // descend down to next trie level + + case *LeafNode[V]: + if pfx.Bits() <= kid.Prefix.Bits() && pfx.Overlaps(kid.Prefix) { + yield(kid.Prefix, kid.Value) + } + return // immediate return + + case *FringeNode[V]: + // get the LPM prefix back from ip and depth + // it's a fringe, bits are always /8, /16, /24, ... + fringePfx, _ := ip.Prefix((depth + 1) << 3) + + if pfx.Bits() <= fringePfx.Bits() && pfx.Overlaps(fringePfx) { + yield(fringePfx, kid.Value) + } + return // immediate return + + default: + panic("logic error, wrong node type") + } + } +} + +// Overlaps recursively compares two trie nodes and returns true +// if any of their prefixes or descendants overlap. +// +// The implementation checks for: +// 1. Direct overlapping prefixes on this node level +// 2. Prefixes in one node overlapping with children in the other +// 3. Matching child addresses in both nodes, which are recursively compared +// +// All 12 possible type combinations for child entries (node, leaf, fringe) are supported. +// +// The function is optimized for early exit on first match and uses heuristics to +// choose between set-based and loop-based matching for performance. +func (n *FastNode[V]) Overlaps(o *FastNode[V], depth int) bool { + nPfxCount := n.PrefixCount() + oPfxCount := o.PrefixCount() + + nChildCount := n.ChildCount() + oChildCount := o.ChildCount() + + // ############################## + // 1. Test if any routes overlaps + // ############################## + + // full cross check + if nPfxCount > 0 && oPfxCount > 0 { + if n.OverlapsRoutes(o) { + return true + } + } + + // #################################### + // 2. Test if routes overlaps any child + // #################################### + + // swap nodes to help chance on its way, + // if the first call to expensive overlapsChildrenIn() is already true, + // if both orders are false it doesn't help either + if nChildCount > oChildCount { + n, o = o, n + + nPfxCount = n.PrefixCount() + oPfxCount = o.PrefixCount() + + nChildCount = n.ChildCount() + oChildCount = o.ChildCount() + } + + if nPfxCount > 0 && oChildCount > 0 { + if n.OverlapsChildrenIn(o) { + return true + } + } + + // symmetric reverse + if oPfxCount > 0 && nChildCount > 0 { + if o.OverlapsChildrenIn(n) { + return true + } + } + + // ############################################ + // 3. children with same octet in nodes n and o + // ############################################ + + // stop condition, n or o have no children + if nChildCount == 0 || oChildCount == 0 { + return false + } + + // stop condition, no child with identical octet in n and o + if !n.Children.Intersects(&o.Children.BitSet256) { + return false + } + + return n.OverlapsSameChildren(o, depth) +} + +// OverlapsRoutes compares the prefix sets of two nodes (n and o). +// +// It first checks for direct bitset intersection (identical indices), +// then walks both prefix sets using the Contains method to detect if any +// of the n-prefixes is contained in o, or vice versa. +func (n *FastNode[V]) OverlapsRoutes(o *FastNode[V]) bool { + // some prefixes are identical, trivial overlap + if n.Prefixes.Intersects(&o.Prefixes.BitSet256) { + return true + } + + // get the lowest idx (biggest prefix) + nFirstIdx, _ := n.Prefixes.FirstSet() + oFirstIdx, _ := o.Prefixes.FirstSet() + + // start with other min value + nIdx := oFirstIdx + oIdx := nFirstIdx + + nOK := true + oOK := true + + // zip, range over n and o together to help chance on its way + for nOK || oOK { + if nOK { + // does any route in o overlap this prefix from n + if nIdx, nOK = n.Prefixes.NextSet(nIdx); nOK { + if o.Contains(nIdx) { + return true + } + + if nIdx == 255 { + // stop, don't overflow uint8! + nOK = false + } else { + nIdx++ + } + } + } + + if oOK { + // does any route in n overlap this prefix from o + if oIdx, oOK = o.Prefixes.NextSet(oIdx); oOK { + if n.Contains(oIdx) { + return true + } + + if oIdx == 255 { + // stop, don't overflow uint8! + oOK = false + } else { + oIdx++ + } + } + } + } + + return false +} + +// OverlapsChildrenIn checks whether the prefixes in node n +// overlap with any children (by address range) in node o. +// +// Uses bitset intersection or manual iteration heuristically, +// depending on prefix and child count. +// +// Bitset-based matching uses precomputed coverage tables +// to avoid per-address looping. This is critical for high fan-out nodes. +func (n *FastNode[V]) OverlapsChildrenIn(o *FastNode[V]) bool { + pfxCount := n.PrefixCount() + childCount := o.ChildCount() + + // heuristic: 15 is the crossover point where bitset operations become + // more efficient than iteration, determined by micro benchmarks on typical + // routing table distributions + const overlapsRangeCutoff = 15 + + doRange := childCount < overlapsRangeCutoff || pfxCount > overlapsRangeCutoff + + // do range over, not so many children and maybe too many prefixes for other algo below + var buf [256]uint8 + if doRange { + for _, addr := range o.Children.AsSlice(&buf) { + if n.Contains(art.OctetToIdx(addr)) { + return true + } + } + return false + } + + // do bitset intersection, alloted route table with child octets + // maybe too many children for range-over or not so many prefixes to + // build the alloted routing table from them + + // use allot table with prefixes as bitsets, bitsets are precalculated. + for _, idx := range n.Prefixes.AsSlice(&buf) { + if o.Children.Intersects(&allot.FringeRoutesLookupTbl[idx]) { + return true + } + } + + return false +} + +// OverlapsSameChildren compares all matching child addresses (octets) +// between node n and node o recursively. +// +// For each shared address, the corresponding child nodes (of any type) +// are compared using FastNodeOverlapsTwoChildren, which handles all +// node/leaf/fringe combinations. +func (n *FastNode[V]) OverlapsSameChildren(o *FastNode[V], depth int) bool { + // intersect the child bitsets from n with o + commonChildren := n.Children.Intersection(&o.Children.BitSet256) + + for addr, ok := commonChildren.NextSet(0); ok; { + nChild := n.MustGetChild(addr) + oChild := o.MustGetChild(addr) + + if n.OverlapsTwoChildren(nChild, oChild, depth+1) { + return true + } + + if addr == 255 { + break // Prevent uint8 overflow + } + + addr, ok = commonChildren.NextSet(addr + 1) + } + return false +} + +// OverlapsPrefixAtDepth returns true if any route in the subtree rooted at this node +// overlaps with the given pfx, starting the comparison at the specified depth. +// +// This function supports structural overlap detection even in compressed or sparse +// paths within the trie, including fringe and leaf nodes. Matching is directional: +// it returns true if a route fully covers pfx, or if pfx covers an existing route. +// +// At each step, it checks for visible prefixes and children that may intersect the +// target prefix via stride-based longest-prefix test. The walk terminates early as +// soon as a structural overlap is found. +// +// This function underlies the top-level OverlapsPrefix behavior and handles details of +// trie traversal across varying prefix lengths and compression levels. +func (n *FastNode[V]) OverlapsPrefixAtDepth(pfx netip.Prefix, depth int) bool { + ip := pfx.Addr() + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + for ; depth < len(octets); depth++ { + if depth > strideCount { + break + } + + octet := octets[depth] + + // full octet path in node trie, check overlap with last prefix octet + if depth == strideCount { + return n.OverlapsIdx(art.PfxToIdx(octet, modBits)) + } + + // test if any route overlaps prefix´ so far + // no best match needed, forward tests without backtracking + if n.PrefixCount() != 0 && n.Contains(art.OctetToIdx(octet)) { + return true + } + + if !n.Children.Test(octet) { + return false + } + + // next child, node or leaf + switch kid := n.MustGetChild(octet).(type) { + case *FastNode[V]: + n = kid + continue + + case *LeafNode[V]: + return kid.Prefix.Overlaps(pfx) + + case *FringeNode[V]: + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable: " + pfx.String()) +} + +// OverlapsIdx returns true if the given prefix index overlaps with any entry in this node. +// +// The overlap detection considers three categories: +// +// 1. Whether any stored prefix in this node covers the requested prefix (LPM test) +// 2. Whether the requested prefix covers any stored route in the node +// 3. Whether the requested prefix overlaps with any fringe or child entry +// +// Internally, it leverages precomputed bitsets from the allotment model, +// using fast bitwise set intersections instead of explicit range comparisons. +// This enables high-performance overlap checks on a single stride level +// without descending further into the trie. +func (n *FastNode[V]) OverlapsIdx(idx uint8) bool { + // 1. Test if any route in this node overlaps prefix? + if n.Contains(idx) { + return true + } + + // 2. Test if prefix overlaps any route in this node + if n.Prefixes.Intersects(&allot.PfxRoutesLookupTbl[idx]) { + return true + } + + // 3. Test if prefix overlaps any child in this node + return n.Children.Intersects(&allot.FringeRoutesLookupTbl[idx]) +} + +// OverlapsTwoChildren handles all 3x3 combinations of +// node kinds (node, leaf, fringe). +// +// 3x3 possible different combinations for n and o +// +// node, node --> overlaps rec descent +// node, leaf --> overlapsPrefixAtDepth +// node, fringe --> true +// +// leaf, node --> overlapsPrefixAtDepth +// leaf, leaf --> netip.Prefix.Overlaps +// leaf, fringe --> true +// +// fringe, node --> true +// fringe, leaf --> true +// fringe, fringe --> true +func (n *FastNode[V]) OverlapsTwoChildren(nChild, oChild any, depth int) bool { + // child type detection + nNode, nIsNode := nChild.(*FastNode[V]) + nLeaf, nIsLeaf := nChild.(*LeafNode[V]) + _, nIsFringe := nChild.(*FringeNode[V]) + + oNode, oIsNode := oChild.(*FastNode[V]) + oLeaf, oIsLeaf := oChild.(*LeafNode[V]) + _, oIsFringe := oChild.(*FringeNode[V]) + + // Handle all 9 combinations with a single expression + switch { + // NODE cases + case nIsNode && oIsNode: + return nNode.Overlaps(oNode, depth) + case nIsNode && oIsLeaf: + return nNode.OverlapsPrefixAtDepth(oLeaf.Prefix, depth) + case nIsNode && oIsFringe: + return true + + // LEAF cases + case nIsLeaf && oIsNode: + return oNode.OverlapsPrefixAtDepth(nLeaf.Prefix, depth) + case nIsLeaf && oIsLeaf: + return oLeaf.Prefix.Overlaps(nLeaf.Prefix) + case nIsLeaf && oIsFringe: + return true + + // FRINGE cases + case nIsFringe: + return true // fringe overlaps with everything + + default: + panic("logic error, wrong node type combination") + } +} diff --git a/vendor/github.com/gaissmai/bart/internal/nodes/lite.go b/vendor/github.com/gaissmai/bart/internal/nodes/lite.go new file mode 100644 index 0000000..df889e7 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/nodes/lite.go @@ -0,0 +1,221 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package nodes + +import ( + "iter" + + "github.com/gaissmai/bart/internal/bitset" + "github.com/gaissmai/bart/internal/lpm" + "github.com/gaissmai/bart/internal/sparse" +) + +// LiteNode is a space-optimized version of [BartNode] that tracks prefix existence +// without storing associated values. +type LiteNode[V any] struct { + Children sparse.Array256[any] + Prefixes struct { + // BitSet256 tracks the presence of prefixes at this level. + bitset.BitSet256 + // Count maintains the current number of set bits, updated on modification + // to avoid expensive population counting. + Count uint16 + } +} + +// IsEmpty returns true if the node contains no routing entries (prefixes) +// and no child nodes. Empty nodes are candidates for compression or removal +// during trie optimization. +func (n *LiteNode[V]) IsEmpty() bool { + if n == nil { + return true + } + return n.Prefixes.Count == 0 && n.Children.Len() == 0 +} + +// PrefixCount returns the number of prefixes stored in this node. +func (n *LiteNode[V]) PrefixCount() int { + return int(n.Prefixes.Count) +} + +// ChildCount returns the number of slots used in this node. +func (n *LiteNode[V]) ChildCount() int { + return n.Children.Len() +} + +// InsertPrefix adds a routing entry at the specified index. +// It returns true if a prefix already existed at that index, +// false if this is a new insertion. +func (n *LiteNode[V]) InsertPrefix(idx uint8, _ V) (exists bool) { + if exists = n.Prefixes.Test(idx); exists { + return exists + } + n.Prefixes.Set(idx) + n.Prefixes.Count++ + return exists +} + +func (n *LiteNode[V]) GetPrefix(idx uint8) (_ V, exists bool) { + // no docstring by intention + exists = n.Prefixes.Test(idx) + return +} + +func (n *LiteNode[V]) MustGetPrefix(idx uint8) (_ V) { + // no docstring by intention + return +} + +// AllIndices returns an iterator over all prefix entries. +// Each iteration yields the prefix index (uint8) and its associated value (V). +func (n *LiteNode[V]) AllIndices() iter.Seq2[uint8, V] { + var zero V + return func(yield func(uint8, V) bool) { + var buf [256]uint8 + for _, idx := range n.Prefixes.AsSlice(&buf) { + if !yield(idx, zero) { + return + } + } + } +} + +// DeletePrefix removes the prefix at the specified index. +// Returns true if the prefix existed, and false otherwise. +func (n *LiteNode[V]) DeletePrefix(idx uint8) (exists bool) { + if exists = n.Prefixes.Test(idx); !exists { + return false + } + n.Prefixes.Clear(idx) + n.Prefixes.Count-- + return true +} + +// InsertChild adds a child node at the specified address (0-255). +// The child can be a *LiteNode[V], *LeafNode, or *FringeNode. +// Returns true if a child already existed at that address. +func (n *LiteNode[V]) InsertChild(addr uint8, child any) (exists bool) { + _, exists = n.Children.InsertAt(addr, child) + return +} + +// GetChild retrieves the child node at the specified address. +// Returns the child and true if found, or nil and false if not present. +func (n *LiteNode[V]) GetChild(addr uint8) (any, bool) { + return n.Children.Get(addr) +} + +// MustGetChild retrieves the child at the specified address, panicking if not found. +// This method should only be used when the caller is certain the child exists. +func (n *LiteNode[V]) MustGetChild(addr uint8) any { + return n.Children.MustGet(addr) +} + +// AllChildren returns an iterator over all child nodes. +// Each iteration yields the child's address (uint8) and the child node (any). +func (n *LiteNode[V]) AllChildren() iter.Seq2[uint8, any] { + return func(yield func(addr uint8, child any) bool) { + var buf [256]uint8 + addrs := n.Children.AsSlice(&buf) + for i, addr := range addrs { + if !yield(addr, n.Children.Items[i]) { + return + } + } + } +} + +// DeleteChild removes the child node at the specified address. +// This operation is idempotent - removing a non-existent child is safe. +func (n *LiteNode[V]) DeleteChild(addr uint8) (exists bool) { + _, exists = n.Children.DeleteAt(addr) + return exists +} + +// Contains returns true if an index (idx) has any matching longest-prefix +// in the current node’s prefix table. +// +// This function performs a presence check. +// +// The prefix table is structured as a complete binary tree (CBT), and LPM testing +// is done via a bitset operation that maps the traversal path from the given index +// toward its possible ancestors. +func (n *LiteNode[V]) Contains(idx uint8) bool { + return n.Prefixes.Intersects(&lpm.LookupTbl[idx]) +} + +// LookupIdx performs a longest-prefix match (LPM) lookup for the given index (idx) +// within the 8-bit stride-based prefix table at this trie depth. +// +// The function returns the matched index and whether a matching prefix +// exists at this level. The value type parameter exists only to satisfy interfaces. +// +// Internally, the prefix table is organized as a complete binary tree (CBT) indexed +// via the baseIndex function. Unlike the original ART algorithm, this implementation +// does not use an allotment-based approach. Instead, it performs CBT backtracking +// using a bitset-based operation with a precomputed backtracking pattern specific to idx. +func (n *LiteNode[V]) LookupIdx(idx uint8) (top uint8, _ V, ok bool) { + top, ok = n.Prefixes.IntersectionTop(&lpm.LookupTbl[idx]) + return +} + +// Lookup is just a simple wrapper for LookupIdx. +func (n *LiteNode[V]) Lookup(idx uint8) (_ V, ok bool) { + _, _, ok = n.LookupIdx(idx) + return +} + +// CloneFlat returns a shallow copy of the current node. +// +// CloneFn is only used for interface satisfaction. +func (n *LiteNode[V]) CloneFlat(_ func(V) V) *LiteNode[V] { + if n == nil { + return nil + } + + c := new(LiteNode[V]) + if n.IsEmpty() { + return c + } + + // copy simple values + c.Prefixes = n.Prefixes + + // sparse array + c.Children = *(n.Children.Copy()) + + // no values to copy + return c +} + +// CloneRec performs a recursive deep copy of the node and all its descendants. +// +// cloneFn is only used for interface satisfaction. +// +// It first creates a shallow clone of the current node using CloneFlat. +// Then it recursively clones all child nodes of type *LiteNode[V], +// performing a full deep clone down the subtree. +// +// Child nodes of type *LeafNode and *FringeNode are already copied +// by CloneFlat. +// +// Returns a new instance of LiteNode[V] which is a complete deep clone of the +// receiver node with all descendants. +func (n *LiteNode[V]) CloneRec(_ func(V) V) *LiteNode[V] { + if n == nil { + return nil + } + + // Perform a flat clone of the current node. + c := n.CloneFlat(nil) + + // Recursively clone all child nodes of type *LiteNode[V] + for i, kidAny := range c.Children.Items { + if kid, ok := kidAny.(*LiteNode[V]); ok { + c.Children.Items[i] = kid.CloneRec(nil) + } + } + + return c +} diff --git a/vendor/github.com/gaissmai/bart/internal/nodes/litemethodsgenerated.go b/vendor/github.com/gaissmai/bart/internal/nodes/litemethodsgenerated.go new file mode 100644 index 0000000..c615cd0 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/nodes/litemethodsgenerated.go @@ -0,0 +1,2427 @@ +// Code generated from file "commonmethods_tmpl.go"; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package nodes + +import ( + "fmt" + "io" + "net/netip" + "slices" + "strings" + + "github.com/gaissmai/bart/internal/allot" + "github.com/gaissmai/bart/internal/art" + "github.com/gaissmai/bart/internal/value" +) + +// Insert adds or updates a network prefix and its associated value in the trie. +// Traversal begins at the specified byte depth. +// +// The trie utilizes path compression to conserve memory. A prefix is inserted: +// - Uncompressed into a node's prefix table at depth == strideCount. +// - As a path-compressed FringeNode if it qualifies as fringe [IsFringe]. +// - As a path-compressed LeafNode otherwise. +// +// When a new prefix collides with an existing compressed node (Leaf or Fringe), +// Insert resolves the collision by creating a new intermediate node, pushing +// the existing entry down to the next level, and continuing traversal. +// +// Parameters: +// - pfx: The network prefix to insert (must be in canonical/masked form). +// - val: The value to associate with the prefix. +// - depth: The current depth in the trie (0-based byte index). +// +// Returns true if an existing prefix was updated, false if a new insertion occurred. +func (n *LiteNode[V]) Insert(pfx netip.Prefix, val V, depth int) (exists bool) { + ip := pfx.Addr() // the pfx must be in canonical form + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the prefix's octets. Each depth corresponds to an 8-bit stride. + // We descend through the trie until we either reach the final stride (depth == strideCount) + // or find an empty child slot where we can path-compress the remaining strides. + for ; depth < len(octets); depth++ { + octet := octets[depth] + + // The current depth matches the prefix's stride count, meaning this is the final + // node for this prefix. We insert it directly into this node's prefix table. + if depth == strideCount { + return n.InsertPrefix(art.PfxToIdx(octet, modBits), val) + } + + // No child exists at this octet path. Instead of creating intermediate nodes + // for the remaining strides, we path-compress the rest of the prefix into a single child slot. + if !n.Children.Test(octet) { + // If the prefix is perfectly aligned with the next stride boundary (e.g., /16 at depth 1), + // it acts as a default route for everything below it. We store it as a FringeNode. + // Otherwise, it has trailing bits or crosses boundaries, so we store it as a LeafNode. + if IsFringe(depth, pfxLen) { + return n.InsertChild(octet, NewFringeNode(val)) + } + return n.InsertChild(octet, NewLeafNode(pfx, val)) + } + + // A child already exists at this octet path. Retrieve it to either continue + // our descent along the strides or resolve a structural collision with a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *LiteNode[V]: + // Standard intermediate node: descend to the next trie level. + n = kid + + case *LeafNode[V]: + // Collision with an existing path-compressed LeafNode. + // If it's the exact same prefix, simply update the value. + if kid.Prefix == pfx { + kid.Value = val + return true + } + + // Collision resolution: the paths diverge. + // 1. Create a new intermediate node. + // 2. Push the existing leaf down into this new node. + // 3. Replace the current child slot with the new node. + // 4. Descend into the new node to continue inserting 'pfx'. + newNode := new(LiteNode[V]) + newNode.Insert(kid.Prefix, kid.Value, depth+1) + + n.InsertChild(octet, newNode) + n = newNode + + case *FringeNode[V]: + // Collision with an existing path-compressed FringeNode. + // If the incoming prefix is also a fringe at this depth, update the value. + if IsFringe(depth, pfxLen) { + kid.Value = val + return true + } + + // Collision resolution: + // The existing FringeNode acts as a catch-all (default route) for this sub-trie. + // To allow the incoming prefix to branch further, we expand the FringeNode + // into a full intermediate node and place its value at the default route index (1). + newNode := new(LiteNode[V]) + newNode.InsertPrefix(1, kid.Value) + + n.InsertChild(octet, newNode) + n = newNode + + default: + panic("logic error, wrong node type") + } + } + panic("unreachable") +} + +// InsertPersist adds or updates a network prefix and its associated value in the trie +// using Copy-On-Write (COW) semantics. Traversal begins at the specified byte depth. +// +// Unlike [Insert], InsertPersist ensures structural integrity of the existing tree +// by cloning internal nodes along the descent path (Copy-On-Write) before mutation. +// +// Parameters: +// - cloneFn: The function used to clone values (V). +// - pfx: The network prefix to insert (must be in canonical/masked form). +// - val: The value to associate with the prefix. +// - depth: The current depth in the trie (0-based byte index). +// +// Returns true if an existing prefix was updated, false if a new insertion occurred. +func (n *LiteNode[V]) InsertPersist(cloneFn func(V) V, pfx netip.Prefix, val V, depth int) (exists bool) { + ip := pfx.Addr() // the pfx must be in canonical form + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the prefix's octets. Each depth corresponds to an 8-bit stride. + // We descend through the trie until we either reach the final stride (depth == strideCount) + // or find an empty child slot where we can path-compress the remaining strides. + for ; depth < len(octets); depth++ { + octet := octets[depth] + + // The current depth matches the prefix's stride count, meaning this is the final + // node for this prefix. We insert it directly into this node's prefix table. + if depth == strideCount { + return n.InsertPrefix(art.PfxToIdx(octet, modBits), val) + } + + // No child exists at this octet path. Instead of creating intermediate nodes + // for the remaining strides, we path-compress the rest of the prefix into a single child slot. + if !n.Children.Test(octet) { + // If the prefix is perfectly aligned with the next stride boundary (e.g., /16 at depth 1), + // it acts as a default route for everything below it. We store it as a FringeNode. + // Otherwise, it has trailing bits or crosses boundaries, so we store it as a LeafNode. + if IsFringe(depth, pfxLen) { + return n.InsertChild(octet, NewFringeNode(val)) + } + return n.InsertChild(octet, NewLeafNode(pfx, val)) + } + + // A child already exists at this octet path. Retrieve it to either continue + // our descent along the strides or resolve a structural collision with a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *LiteNode[V]: + // Standard intermediate node: Clone the traversed path to maintain persistence (COW). + // We clone the child node before modifying it, then replace the current child slot. + kid = kid.CloneFlat(cloneFn) + n.InsertChild(octet, kid) + n = kid + + case *LeafNode[V]: + // Collision with an existing path-compressed LeafNode. + // If it's the exact same prefix, simply update the value. + if kid.Prefix == pfx { + kid.Value = val + return true + } + + // Collision resolution: the paths diverge. + // 1. Create a new intermediate node. + // 2. Push the existing leaf down into this new node. + // 3. Replace the current child slot with the new node. + // 4. Descend into the new node to continue inserting 'pfx'. + newNode := new(LiteNode[V]) + newNode.Insert(kid.Prefix, kid.Value, depth+1) + + n.InsertChild(octet, newNode) + n = newNode + + case *FringeNode[V]: + // Collision with an existing path-compressed FringeNode. + // If the incoming prefix is also a fringe at this depth, update the value. + if IsFringe(depth, pfxLen) { + kid.Value = val + return true + } + + // Collision resolution: + // The existing FringeNode acts as a catch-all (default route) for this sub-trie. + // To allow the incoming prefix to branch further, we expand the FringeNode + // into a full intermediate node and place its value at the default route index (1). + newNode := new(LiteNode[V]) + newNode.InsertPrefix(1, kid.Value) + + n.InsertChild(octet, newNode) + n = newNode + + default: + panic("logic error, wrong node type") + } + } + panic("unreachable") +} + +// PurgeAndCompress performs bottom-up trie maintenance to restore path compression +// after a deletion. It unwinds the provided stack of parent nodes, identifying +// nodes that have become sparse (i.e., containing only a single prefix or a single +// child node) and prunes them by promoting the underlying entries to the parent level. +// +// This ensures the trie remains memory-efficient by collapsing redundant intermediate +// nodes back into path-compressed LeafNodes or FringeNodes whenever possible. +// +// Parameters: +// - stack: Array of parent nodes to process during bottom-up unwinding. +// - octets: The full path of octets leading to the current node. +// - is4: True for IPv4 processing, false for IPv6. +func (n *LiteNode[V]) PurgeAndCompress(stack []*LiteNode[V], octets []uint8, is4 bool) { + // Iterate backwards through the ancestor stack to prune nodes from the bottom up. + for depth := len(stack) - 1; depth >= 0; depth-- { + parent := stack[depth] + octet := octets[depth] + + // Check if the current node is redundant. + // A node may be redundant if it contains exactly one entry (either a prefix or + // a compressed child node). + pfxCount := n.PrefixCount() + childCount := n.ChildCount() + + // If it contains more than one entry, it is always structurally significant and cannot be pruned. + if pfxCount+childCount > 1 { + return + } + + switch { + case childCount == 1: + // The node has exactly one child. We determine if it is a path node, + // a compressed LeafNode, or a compressed FringeNode. + singleAddr, _ := n.Children.FirstSet() + anyKid := n.MustGetChild(singleAddr) + + switch kid := anyKid.(type) { + case *LiteNode[V]: + // The child is an intermediate path node; the tree structure is required + // at this level. Compression cannot proceed further up. + return + case *LeafNode[V]: + // The child is a compressed LeafNode. Prune the current node + // and re-insert the leaf into the parent to elevate it. + parent.DeleteChild(octet) + parent.Insert(kid.Prefix, kid.Value, depth) + case *FringeNode[V]: + // The child is a compressed FringeNode. Prune the current node + // and re-insert the fringe as a leaf into the parent. + parent.DeleteChild(octet) + + // Reconstruct the full prefix for the fringe, as path compression + // requires the entire CIDR path, not just the remainder. + // depth is the parent's depth, so we offset by 1 for the kid's position. + fringePfx := CidrForFringe(octets, depth+1, is4, singleAddr) + + parent.Insert(fringePfx, kid.Value, depth) + } + + case pfxCount == 1: + // The node has exactly one prefix. Prune the node and elevate the + // prefix to the parent level as a leaf/fringe. + parent.DeleteChild(octet) + + // Retrieve the single prefix stored in this node. + idx, _ := n.Prefixes.FirstSet() + val := n.MustGetPrefix(idx) + + // Reconstruct the prefix from the path for re-insertion. + path := StridePath{} + copy(path[:], octets) + pfx := CidrFromPath(path, depth+1, is4, idx) + + parent.Insert(pfx, val, depth) + default: + panic("unreachable") + } + + // Move up to the next parent in the stack to continue pruning. + n = parent + } +} + +// Delete removes the prefix from the trie rooted at n and returns true if the +// prefix existed, false if it was not found. The prefix must be in canonical +// (masked) form. +// +// The trie uses path compression, so a prefix may be stored in one of three ways: +// - In the current node's prefix table when the prefix length aligns exactly +// with the stride boundary at this depth (depth == strideCount). +// - As a path-compressed FringeNode in a child slot for stride-aligned prefixes +// (e.g. /8, /16, /24); occurs at depth == strideCount-1. +// - As a path-compressed LeafNode in a child slot for prefixes otherwise. +// +// After a successful deletion, PurgeAndCompress walks the ancestor stack to prune +// now-empty nodes and restore path compression upward. +func (n *LiteNode[V]) Delete(pfx netip.Prefix) (exists bool) { + ip := pfx.Addr() // pfx must be in canonical (masked) form + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Record ancestor nodes as we descend; PurgeAndCompress uses this stack to + // walk back up and clean up empty or re-compressible nodes after deletion. + stack := [MaxTreeDepth]*LiteNode[V]{} + + for depth, octet := range octets { + depth &= DepthMask // BCE hint; keep Delete on the fast path + + stack[depth] = n // record current node before descending + + // At the stride boundary, the prefix is stored directly in this node's + // prefix table. + if depth == strideCount { + if exists = n.DeletePrefix(art.PfxToIdx(octet, modBits)); !exists { + return false + } + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + } + + // no child node exists at this octet; the prefix is not in the trie + if !n.Children.Test(octet) { + return false + } + + // A child node exists at this octet path, retrieve it. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *LiteNode[V]: + n = kid // descend to the next trie level + + case *FringeNode[V]: + // A FringeNode holds a single stride-aligned prefix (/8, /16, ...). + // If pfx does not qualify as a fringe at this depth, it cannot be here. + if !IsFringe(depth, pfxLen) { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + case *LeafNode[V]: + // A LeafNode holds exactly one path-compressed prefix. + // Compare using the canonical (masked) form for an exact match. + if kid.Prefix != pfx { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// DeletePersist removes the prefix from the trie rooted at n using Copy-On-Write (COW) semantics. +// It returns true if the prefix existed, false if it was not found. The prefix must be in +// canonical (masked) form. +// +// Like [Delete], this method uses path compression. However, DeletePersist ensures +// the structural integrity of the existing tree by cloning internal nodes along the +// descent path (COW) before mutation. +// +// After a successful deletion, PurgeAndCompress walks the ancestor stack to prune +// now-empty nodes and restore path compression upward. +func (n *LiteNode[V]) DeletePersist(cloneFn func(V) V, pfx netip.Prefix) (exists bool) { + ip := pfx.Addr() // pfx must be in canonical (masked) form + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Record ancestor nodes as we descend; PurgeAndCompress uses this stack to + // walk back up and clean up empty or re-compressible nodes after deletion. + // Since this is a COW operation, we store the cloned nodes here. + stack := [MaxTreeDepth]*LiteNode[V]{} + + for depth, octet := range octets { + depth &= DepthMask // BCE hint; keep DeletePersist on the fast path + stack[depth] = n // record current node before descending + + // At the stride boundary, the prefix is stored directly in this node's + // prefix table. + if depth == strideCount { + if exists = n.DeletePrefix(art.PfxToIdx(octet, modBits)); !exists { + return false + } + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + } + + // no child node exists at this octet; the prefix is not in the trie + if !n.Children.Test(octet) { + return false + } + + // A child node exists at this octet path, retrieve it to either continue + // our descent or perform a persistent delete on a compressed node. + kid := n.MustGetChild(octet) + + switch kid := kid.(type) { + case *LiteNode[V]: + // Standard intermediate node: Clone the traversed path to maintain + // persistence (COW). We clone the child node before modifying it, + // then replace the current child slot. + kid = kid.CloneFlat(cloneFn) + n.InsertChild(octet, kid) + n = kid + continue + + case *FringeNode[V]: + // A FringeNode holds a single stride-aligned prefix (/8, /16, ...). + // If pfx does not qualify as a fringe at this depth, it cannot be here. + if !IsFringe(depth, pfxLen) { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + case *LeafNode[V]: + // A LeafNode holds exactly one path-compressed prefix. + // Compare using the canonical (masked) form for an exact match. + if kid.Prefix != pfx { + return false + } + + n.DeleteChild(octet) + + // prune now-empty nodes and re-compress the path upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// Get retrieves the value associated with the given network prefix. +// Traversal descends through the trie using the prefix's octets. +// +// The lookup handles path compression transparently: +// - If the path matches an internal node at the target stride, the value is retrieved +// from the node's prefix table. +// - If the path leads to a compressed LeafNode or FringeNode, the function verifies +// the prefix match before returning the value. +// +// Parameters: +// - pfx: The network prefix to look up (must be in canonical form). +// +// Returns: +// - val: The value associated with the prefix (zero value if not found). +// - exists: True if the prefix was found, false otherwise. +func (n *LiteNode[V]) Get(pfx netip.Prefix) (val V, exists bool) { + // The prefix must be provided in canonical (masked) form for correct trie traversal. + ip := pfx.Addr() + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // Traverse the trie octet by octet based on the prefix path. + for depth, octet := range octets { + // At the target stride boundary, the prefix is expected in this node's + // prefix table. + if depth == strideCount { + return n.GetPrefix(art.PfxToIdx(octet, modBits)) + } + + // If no child exists at this path, the prefix is not in the trie. + kidAny, ok := n.GetChild(octet) + if !ok { + return val, false + } + + // Identify the node type at this path segment. + switch kid := kidAny.(type) { + case *LiteNode[V]: + // Standard intermediate node: descend to the next level. + n = kid + + case *FringeNode[V]: + // Reached a path-compressed FringeNode. + // Verify if the prefix qualifies as a fringe at this depth to return a match. + if IsFringe(depth, pfxLen) { + return kid.Value, true + } + return val, false + + case *LeafNode[V]: + // Reached a path-compressed LeafNode. + // Check if the stored prefix matches the lookup prefix exactly. + if kid.Prefix == pfx { + return kid.Value, true + } + return val, false + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// Modify performs an in-place modification of a prefix using the provided callback function. +// The callback receives the current value (if found) and existence flag, and returns +// a new value and deletion flag. +// +// Modify returns the size delta (-1, 0, +1). +// This method handles path traversal, node creation for new paths, and automatic +// purge/compress operations after deletions. +// +// Parameters: +// - pfx: The network prefix to modify (must be in canonical form) +// - cb: Callback function that receives (currentValue, exists) and returns (newValue, deleteFlag) +// +// Returns: +// - delta: Size change (-1 for delete, 0 for update/noop, +1 for insert) +func (n *LiteNode[V]) Modify(pfx netip.Prefix, cb func(val V, found bool) (_ V, del bool)) (delta int) { + var zero V + + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // record the nodes on the path to the deleted node, needed to purge + // and/or path compress nodes after the deletion of a prefix + stack := [MaxTreeDepth]*LiteNode[V]{} + + // find the proper trie node to update prefix + for depth, octet := range octets { + depth &= DepthMask // BCE + + // push current node on stack for path recording + stack[depth] = n + + // The current depth matches the prefix's stride count, meaning this is the final + // stride for this prefix. Insert or update it directly in this node's prefix table. + if depth == strideCount { + idx := art.PfxToIdx(octet, modBits) + + oldVal, existed := n.GetPrefix(idx) + newVal, del := cb(oldVal, existed) + + // update size if necessary + switch { + case !existed && del: // no-op + return 0 + + case existed && del: // delete + n.DeletePrefix(idx) + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + return -1 + + case !existed: // insert + n.InsertPrefix(idx, newVal) + return 1 + + case existed: // update + n.InsertPrefix(idx, newVal) + return 0 + + default: + panic("unreachable") + } + + } + + // go down in tight loop to last octet + if !n.Children.Test(octet) { + // insert prefix path compressed + + newVal, del := cb(zero, false) + if del { + return 0 + } + + // insert + if IsFringe(depth, pfxLen) { + n.InsertChild(octet, NewFringeNode(newVal)) + } else { + n.InsertChild(octet, NewLeafNode(pfx, newVal)) + } + + return 1 + } + + // n.children.Test(octet) == true + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *LiteNode[V]: + n = kid // descend down to next trie level + continue + + case *LeafNode[V]: + oldVal := kid.Value + + // update existing value if prefixes are equal + if kid.Prefix == pfx { + newVal, del := cb(oldVal, true) + + if !del { + kid.Value = newVal + return 0 + } + + // delete + n.DeleteChild(octet) + + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + + return -1 + } + + // stop if this is a no-op for zero values + newVal, del := cb(zero, false) + if del { + return 0 + } + + // create new node + // insert new child at current leaf position (octet) + newNode := new(LiteNode[V]) + n.InsertChild(octet, newNode) + + // push the leaf down + // insert pfx with newVal in new node + newNode.Insert(kid.Prefix, kid.Value, depth+1) + newNode.Insert(pfx, newVal, depth+1) + + return 1 + + case *FringeNode[V]: + // update existing value if prefix is fringe + if IsFringe(depth, pfxLen) { + newVal, del := cb(kid.Value, true) + if !del { + kid.Value = newVal + return 0 + } + + // delete + n.DeleteChild(octet) + + // remove now-empty nodes and re-path-compress upwards + n.PurgeAndCompress(stack[:depth], octets, is4) + + return -1 + } + + // stop if this is a no-op for zero values + newVal, del := cb(zero, false) + if del { + return 0 + } + + // create new node + // insert new child at current leaf position (octet) + newNode := new(LiteNode[V]) + n.InsertChild(octet, newNode) + + // push the fringe down, it becomes a default route (idx=1) + // insert pfx with newVal in new node + newNode.InsertPrefix(1, kid.Value) + newNode.Insert(pfx, newVal, depth+1) + + return 1 + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable") +} + +// EqualRec performs recursive structural equality comparison between two nodes. +// Compares prefix and child bitsets, then recursively compares all stored values +// and child nodes. Returns true if the nodes and their entire subtrees are +// structurally and semantically identical, false otherwise. +// +// The comparison handles different node types (internal nodes, leafNodes, fringeNodes) +// and uses the equal function for value comparisons to support custom equality logic. +func (n *LiteNode[V]) EqualRec(o *LiteNode[V]) bool { + if n == nil || o == nil { + return n == o + } + if n == o { + return true + } + + if n.Prefixes.BitSet256 != o.Prefixes.BitSet256 { + return false + } + + if n.Children.BitSet256 != o.Children.BitSet256 { + return false + } + + for idx, nVal := range n.AllIndices() { + oVal := o.MustGetPrefix(idx) // mustGet is ok, bitsets are equal + if !value.Equal(nVal, oVal) { + return false + } + } + + for addr, nKid := range n.AllChildren() { + oKid := o.MustGetChild(addr) // mustGet is ok, bitsets are equal + + switch nKid := nKid.(type) { + case *LiteNode[V]: + // oKid must also be a node + oKid, ok := oKid.(*LiteNode[V]) + if !ok { + return false + } + + // compare rec-descent + if !nKid.EqualRec(oKid) { + return false + } + + case *LeafNode[V]: + // oKid must also be a leaf + oKid, ok := oKid.(*LeafNode[V]) + if !ok { + return false + } + + // compare prefixes + if nKid.Prefix != oKid.Prefix { + return false + } + + // compare values + if !value.Equal(nKid.Value, oKid.Value) { + return false + } + + case *FringeNode[V]: + // oKid must also be a fringe + oKid, ok := oKid.(*FringeNode[V]) + if !ok { + return false + } + + // compare values + if !value.Equal(nKid.Value, oKid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// DumpRec recursively descends the trie rooted at n and writes a human-readable +// representation of each visited node to w. +// +// It returns immediately if n is nil or empty. For each visited internal node +// it calls dump to write the node's representation, then iterates its child +// addresses and recurses into children of type *LiteNode[V] (internal subnodes). +// The path slice and depth together represent the byte-wise path +// from the root to the current node; depth is incremented for each recursion. +// The is4 flag controls IPv4/IPv6 formatting used by dump. +func (n *LiteNode[V]) DumpRec(w io.Writer, path StridePath, depth int, is4 bool) { + if n == nil || n.IsEmpty() { + return + } + + // dump this node + n.dump(w, path, depth, is4) + + // node may have children, rec-descent down + for addr, child := range n.AllChildren() { + if kid, ok := child.(*LiteNode[V]); ok { + path[depth] = addr + kid.DumpRec(w, path, depth+1, is4) + } + } +} + +// dump writes a human-readable representation of the node to `w`. +// It prints the node type, depth, formatted path (IPv4 vs IPv6 controlled by `is4`), +// and bit count, followed by any stored prefixes (and their values when applicable), +// the set of child octets, and any path-compressed leaves or fringe entries. +func (n *LiteNode[V]) dump(w io.Writer, path StridePath, depth int, is4 bool) { + bits := depth * strideLen + indent := strings.Repeat(".", depth) + + // printing values if V is not the empty struct{} + printValues := !value.IsEmptyStruct[V]() + + // node type with depth and octet path and bits. + fmt.Fprintf(w, "\n%s[%s] depth: %d path: [%s] / %d\n", + indent, n.hasType(), depth, ipStridePath(path, depth, is4), bits) + + if nPfxCount := n.PrefixCount(); nPfxCount != 0 { + var buf [256]uint8 + allIndices := n.Prefixes.AsSlice(&buf) + + // print the baseIndices for this node. + fmt.Fprintf(w, "%sindexs(#%d): %v\n", indent, nPfxCount, allIndices) + + // print the prefixes for this node + fmt.Fprintf(w, "%sprefxs(#%d):", indent, nPfxCount) + + for _, idx := range allIndices { + pfx := CidrFromPath(path, depth, is4, idx) + fmt.Fprintf(w, " %s", pfx) + } + + fmt.Fprintln(w) + + // skip printing values if V is zero-sized + if printValues { + + // print the values for this node + fmt.Fprintf(w, "%svalues(#%d):", indent, nPfxCount) + + for _, idx := range allIndices { + val := n.MustGetPrefix(idx) + fmt.Fprintf(w, " %#v", val) + } + + fmt.Fprintln(w) + } + } + + if cc := n.ChildCount(); cc != 0 { + allAddrs := make([]uint8, 0, cc) + childAddrs := make([]uint8, 0, cc) + leafAddrs := make([]uint8, 0, cc) + fringeAddrs := make([]uint8, 0, cc) + + // the node has recursive child nodes or path-compressed leaves + for addr, child := range n.AllChildren() { + allAddrs = append(allAddrs, addr) + + switch child.(type) { + case *LiteNode[V]: + childAddrs = append(childAddrs, addr) + continue + + case *FringeNode[V]: + fringeAddrs = append(fringeAddrs, addr) + + case *LeafNode[V]: + leafAddrs = append(leafAddrs, addr) + + default: + panic("logic error, wrong node type") + } + } + + // print the children for this node. + fmt.Fprintf(w, "%soctets(#%d): %v\n", indent, len(allAddrs), allAddrs) + + if leafCount := len(leafAddrs); leafCount > 0 { + // print the pathcomp prefixes for this node + fmt.Fprintf(w, "%sleaves(#%d):", indent, leafCount) + + for _, addr := range leafAddrs { + kid := n.MustGetChild(addr).(*LeafNode[V]) + + // skip printing values if V is zero-sized + if printValues { + fmt.Fprintf(w, " %s:{%s, %v}", addrFmt(addr, is4), kid.Prefix, kid.Value) + } else { + fmt.Fprintf(w, " %s:{%s}", addrFmt(addr, is4), kid.Prefix) + } + } + + fmt.Fprintln(w) + } + + if fringeCount := len(fringeAddrs); fringeCount > 0 { + // print the pathcomp prefixes for this node + fmt.Fprintf(w, "%sfringe(#%d):", indent, fringeCount) + + for _, addr := range fringeAddrs { + fringePfx := CidrForFringe(path[:], depth, is4, addr) + + kid := n.MustGetChild(addr).(*FringeNode[V]) + + // skip printing values if V is zero-sized + if printValues { + fmt.Fprintf(w, " %s:{%s, %v}", addrFmt(addr, is4), fringePfx, kid.Value) + } else { + fmt.Fprintf(w, " %s:{%s}", addrFmt(addr, is4), fringePfx) + } + } + + fmt.Fprintln(w) + } + + if childCount := len(childAddrs); childCount > 0 { + // print the next child + fmt.Fprintf(w, "%schilds(#%d):", indent, childCount) + + for _, addr := range childAddrs { + fmt.Fprintf(w, " %s", addrFmt(addr, is4)) + } + + fmt.Fprintln(w) + } + + } +} + +// DumpString traverses the trie to the node at the specified depth along the given +// octet path and returns its string representation via Dump. +// +// If the path is invalid or encounters an unexpected node type during traversal, +// it returns an error message string instead. +// +// Parameters: +// - octets: The path of octets to follow from the root +// - depth: Target depth to reach before dumping (0-based byte index) +// - is4: True for IPv4 formatting, false for IPv6 +// +// Returns a formatted string representation of the target node or an error message. +func (n *LiteNode[V]) DumpString(octets []uint8, depth int, is4 bool) string { + path := StridePath{} + copy(path[:], octets) + + buf := new(strings.Builder) + for i := range depth { + anyKid, ok := n.GetChild(path[i]) + if !ok { + return fmt.Sprintf("ERROR: kid for %v[%d] is NOT set in node\n", octets, i) + } + + kid, ok := anyKid.(*LiteNode[V]) + if !ok { + return fmt.Sprintf("ERROR: kid for %v[%d] is NO %s\n", octets, i, "LiteNode[V]") + } + + // traverse + n = kid + } + + n.dump(buf, path, depth, is4) + return buf.String() +} + +// hasType classifies the given node into one of the nodeType values. +// +// It inspects immediate statistics (prefix count, child count, node, leaf and +// fringe counts) for the node and returns: +// - nullNode: no prefixes and no children +// - stopNode: has children but no subnodes (nodes == 0) +// - halfNode: contains at least one leaf or fringe and also has subnodes, but +// no prefixes +// - fullNode: has prefixes and also has subnodes +// - pathNode: has subnodes only (no prefixes, leaves, or fringes) +// +// The order of these checks is significant to ensure the correct classification. +func (n *LiteNode[V]) hasType() nodeType { + s := n.Stats() + + // the order is important + switch { + case s.Prefixes == 0 && s.Children == 0: + return nullNode + case s.SubNodes == 0: + return stopNode + case (s.Leaves > 0 || s.Fringes > 0) && s.SubNodes > 0 && s.Prefixes == 0: + return halfNode + case (s.Prefixes > 0 || s.Leaves > 0 || s.Fringes > 0) && s.SubNodes > 0: + return fullNode + case (s.Prefixes == 0 && s.Leaves == 0 && s.Fringes == 0) && s.SubNodes > 0: + return pathNode + default: + panic(fmt.Sprintf("UNREACHABLE: pfx: %d, chld: %d, node: %d, leaf: %d, fringe: %d", + s.Prefixes, s.Children, s.SubNodes, s.Leaves, s.Fringes)) + } +} + +// Stats returns immediate statistics for n: counts of prefixes and children, +// and a classification of each child into nodes, leaves, or fringes. +// It inspects only the direct children of n (not the whole subtree). +// Panics if a child has an unexpected concrete type. +func (n *LiteNode[V]) Stats() (s StatsT) { + s.Prefixes = n.PrefixCount() + s.Children = n.ChildCount() + + for _, child := range n.AllChildren() { + switch child.(type) { + case *LiteNode[V]: + s.SubNodes++ + + case *FringeNode[V]: + s.Fringes++ + + case *LeafNode[V]: + s.Leaves++ + + default: + panic("logic error, wrong node type") + } + } + + return s +} + +// StatsRec returns aggregated statistics for the subtree rooted at n. +// +// It walks the node tree recursively and sums immediate counts (prefixes and +// child slots) plus the number of nodes, leaves, and fringe nodes in the +// subtree. If n is nil or empty, a zeroed stats is returned. The returned +// SubNodes count includes the current node. The function will panic if a child +// has an unexpected concrete type. +func (n *LiteNode[V]) StatsRec() (s StatsT) { + if n == nil || n.IsEmpty() { + return s + } + + s.Prefixes = n.PrefixCount() + s.Children = n.ChildCount() + s.SubNodes = 1 // this node + s.Leaves = 0 + s.Fringes = 0 + + for _, child := range n.AllChildren() { + switch kid := child.(type) { + case *LiteNode[V]: + // rec-descent + rs := kid.StatsRec() + + s.Prefixes += rs.Prefixes + s.Children += rs.Children + s.SubNodes += rs.SubNodes + s.Leaves += rs.Leaves + s.Fringes += rs.Fringes + + case *FringeNode[V]: + s.Fringes++ + + case *LeafNode[V]: + s.Leaves++ + + default: + panic("logic error, wrong node type") + } + } + + return s +} + +// FprintRec recursively prints a hierarchical CIDR tree representation +// starting from this node to the provided writer. The output shows the +// routing table structure in human-readable format for debugging and analysis. +func (n *LiteNode[V]) FprintRec(w io.Writer, parent TrieItem[V], pad string) error { + // recursion stop condition + if n == nil || n.IsEmpty() { + return nil + } + + // get direct covered childs for this parent ... + directItems := n.DirectItemsRec(parent.Idx, parent.Path, parent.Depth, parent.Is4) + + // sort them by netip.Prefix, not by baseIndex + slices.SortFunc(directItems, func(a, b TrieItem[V]) int { + return CmpPrefix(a.Cidr, b.Cidr) + }) + + // printing values if V is not the empty struct{} + printValues := !value.IsEmptyStruct[V]() + + // for all direct item under this node ... + for i, item := range directItems { + // symbols used in tree + glyph := "├─ " + space := "│ " + + // ... treat last kid special + if i == len(directItems)-1 { + glyph = "└─ " + space = " " + } + + var err error + // val is the empty struct, don't print it + if printValues { + _, err = fmt.Fprintf(w, "%s%s (%v)\n", pad+glyph, item.Cidr, item.Val) + } else { + // skip printing values if V is zero-sized + _, err = fmt.Fprintf(w, "%s%s\n", pad+glyph, item.Cidr) + } + + if err != nil { + return err + } + + // rec-descent with this item as parent + nextNode, _ := item.Node.(*LiteNode[V]) + if err = nextNode.FprintRec(w, item, pad+space); err != nil { + return err + } + } + + return nil +} + +// DirectItemsRec, returns the direct covered items by parent. +// It's a complex recursive function, you have to know the data structure +// by heart to understand this function! +func (n *LiteNode[V]) DirectItemsRec(parentIdx uint8, path StridePath, depth int, is4 bool) (directItems []TrieItem[V]) { + // recursion stop condition + if n == nil || n.IsEmpty() { + return nil + } + + // prefixes: + // for all idx's (prefixes mapped by baseIndex) in this node + // do a longest-prefix-match + for idx, val := range n.AllIndices() { + // tricky part, skip self + // test with next possible lpm (idx>>1), it's a complete binary tree + nextIdx := idx >> 1 + + // fast skip, lpm not possible + if nextIdx < parentIdx { + continue + } + + // do a longest-prefix-match + lpm, _, _ := n.LookupIdx(nextIdx) + + // be aware, 0 is here a possible value for parentIdx and lpm (if not found) + if lpm == parentIdx { + // prefix is directly covered by parent + + item := TrieItem[V]{ + Node: n, + Is4: is4, + Path: path, + Depth: depth, + Idx: idx, + // get the prefix back from trie + Cidr: CidrFromPath(path, depth, is4, idx), + Val: val, + } + + directItems = append(directItems, item) + } + } + + // children: + for addr, child := range n.AllChildren() { + hostIdx := art.OctetToIdx(addr) + + // do a longest-prefix-match + lpm, _, _ := n.LookupIdx(hostIdx) + + // be aware, 0 is here a possible value for parentIdx and lpm (if not found) + if lpm == parentIdx { + // child is directly covered by parent + switch kid := child.(type) { + case *LiteNode[V]: // traverse rec-descent, call with next child node, + // next trie level, set parentIdx to 0, adjust path and depth + path[depth] = addr + directItems = append(directItems, kid.DirectItemsRec(0, path, depth+1, is4)...) + + case *LeafNode[V]: // path-compressed child, stops recursion for this child + item := TrieItem[V]{ + Node: nil, + Is4: is4, + Cidr: kid.Prefix, + Val: kid.Value, + } + directItems = append(directItems, item) + + case *FringeNode[V]: // path-compressed fringe, stops recursion for this child + item := TrieItem[V]{ + Node: nil, + Is4: is4, + // get the prefix back from trie + Cidr: CidrForFringe(path[:], depth, is4, addr), + Val: kid.Value, + } + directItems = append(directItems, item) + + default: + panic("logic error, wrong node type") + } + } + } + + return directItems +} + +// UnionRec recursively merges another node o into the receiver node n. +// +// All prefix and child entries from o are cloned and inserted into n. +// If a prefix already exists in n, its value is overwritten by the value from o, +// and the duplicate is counted in the return value. This count can later be used +// to update size-related metadata in the parent trie. +// +// The union handles all possible combinations of child node types (node, leaf, fringe) +// between the two nodes. Structural conflicts are resolved by creating new intermediate +// *LiteNode[V] objects and pushing both children further down the trie. Leaves and fringes +// are also recursively relocated as needed to preserve prefix semantics. +// +// The merge operation is destructive on the receiver n, but leaves the source node o unchanged. +// +// Returns the number of duplicate prefixes that were overwritten during merging. +func (n *LiteNode[V]) UnionRec(cloneFn func(V) V, o *LiteNode[V], depth int) (duplicates int) { + if cloneFn == nil { + cloneFn = func(v V) V { return v } + } + + buf := [256]uint8{} + + // for all prefixes in other node do ... + for _, oIdx := range o.Prefixes.AsSlice(&buf) { + // clone/copy the value from other node at idx + val := o.MustGetPrefix(oIdx) + clonedVal := cloneFn(val) + + // insert/overwrite cloned value from o into n + if n.InsertPrefix(oIdx, clonedVal) { + // this prefix is duplicate in n and o + duplicates++ + } + } + + // for all child addrs in other node do ... + for _, addr := range o.Children.AsSlice(&buf) { + otherChild := o.MustGetChild(addr) + thisChild, thisExists := n.GetChild(addr) + + // Use helper function to handle all 4x3 combinations + duplicates += n.handleMatrix(cloneFn, thisExists, thisChild, otherChild, addr, depth) + } + + return duplicates +} + +// UnionRecPersist is similar to unionRec but performs an immutable union of nodes. +func (n *LiteNode[V]) UnionRecPersist(cloneFn func(V) V, o *LiteNode[V], depth int) (duplicates int) { + if cloneFn == nil { + cloneFn = func(v V) V { return v } + } + + buf := [256]uint8{} + + // for all prefixes in other node do ... + for _, oIdx := range o.Prefixes.AsSlice(&buf) { + // clone/copy the value from other node + val := o.MustGetPrefix(oIdx) + clonedVal := cloneFn(val) + + // insert/overwrite cloned value from o into n + if exists := n.InsertPrefix(oIdx, clonedVal); exists { + // this prefix is duplicate in n and o + duplicates++ + } + } + + // for all child addrs in other node do ... + for _, addr := range o.Children.AsSlice(&buf) { + otherChild := o.MustGetChild(addr) + thisChild, thisExists := n.GetChild(addr) + + // Use helper function to handle all 4x3 combinations + duplicates += n.handleMatrixPersist(cloneFn, thisExists, thisChild, otherChild, addr, depth) + } + + return duplicates +} + +// handleMatrix, 12 possible combinations to union this child and other child +// +// THIS, OTHER: (always clone the other kid!) +// -------------- +// NULL, node <-- insert node at addr +// NULL, leaf <-- insert leaf at addr +// NULL, fringe <-- insert fringe at addr +// +// node, node <-- union rec-descent with node +// node, leaf <-- insert leaf at depth+1 +// node, fringe <-- insert fringe at depth+1 +// +// leaf, node <-- insert new node, push this leaf down, union rec-descent +// leaf, leaf <-- insert new node, push both leaves down (!first check equality) +// leaf, fringe <-- insert new node, push this leaf and fringe down +// +// fringe, node <-- insert new node, push this fringe down, union rec-descent +// fringe, leaf <-- insert new node, push this fringe down, insert other leaf at depth+1 +// fringe, fringe <-- just overwrite value +func (n *LiteNode[V]) handleMatrix(cloneFn func(V) V, thisExists bool, thisChild, otherChild any, addr uint8, depth int) int { + // Do ALL type assertions upfront - reduces line noise + var ( + thisNode, thisIsNode = thisChild.(*LiteNode[V]) + thisLeaf, thisIsLeaf = thisChild.(*LeafNode[V]) + thisFringe, thisIsFringe = thisChild.(*FringeNode[V]) + + otherNode, otherIsNode = otherChild.(*LiteNode[V]) + otherLeaf, otherIsLeaf = otherChild.(*LeafNode[V]) + otherFringe, otherIsFringe = otherChild.(*FringeNode[V]) + ) + + // just insert cloned child at this empty slot + if !thisExists { + switch { + case otherIsNode: + n.InsertChild(addr, otherNode.CloneRec(cloneFn)) + case otherIsLeaf: + n.InsertChild(addr, &LeafNode[V]{Prefix: otherLeaf.Prefix, Value: cloneFn(otherLeaf.Value)}) + case otherIsFringe: + n.InsertChild(addr, &FringeNode[V]{Value: cloneFn(otherFringe.Value)}) + default: + panic("logic error, wrong node type") + } + return 0 + } + + // Case 1: Special cases that DON'T need a new node + + // Special case: fringe + fringe -> just overwrite value + if thisIsFringe && otherIsFringe { + thisFringe.Value = cloneFn(otherFringe.Value) + return 1 + } + + // Special case: leaf + leaf with same prefix -> just overwrite value + if thisIsLeaf && otherIsLeaf && thisLeaf.Prefix == otherLeaf.Prefix { + thisLeaf.Value = cloneFn(otherLeaf.Value) + return 1 + } + + // Case 2: thisChild is already a node - insert into it, no new node needed + if thisIsNode { + switch { + case otherIsNode: + return thisNode.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if thisNode.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if thisNode.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong node type") + } + } + + // Case 3: All remaining cases need a new node + // (thisChild is leaf or fringe, and we didn't hit the special cases above) + + nc := new(LiteNode[V]) + + // Push existing child down into new node + switch { + case thisIsLeaf: + nc.Insert(thisLeaf.Prefix, thisLeaf.Value, depth+1) + case thisIsFringe: + nc.InsertPrefix(1, thisFringe.Value) + default: + panic("logic error, unexpected this child type") + } + + // Replace child with new node + n.InsertChild(addr, nc) + + // Now handle other child + switch { + case otherIsNode: + return nc.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if nc.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if nc.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong other node type") + } +} + +// handleMatrixPersist, 12 possible combinations to union this child and other child +// +// THIS, OTHER: (always clone the other kid!) +// -------------- +// NULL, node <-- insert node at addr +// NULL, leaf <-- insert leaf at addr +// NULL, fringe <-- insert fringe at addr +// +// node, node <-- union rec-descent with node +// node, leaf <-- insert leaf at depth+1 +// node, fringe <-- insert fringe at depth+1 +// +// leaf, node <-- insert new node, push this leaf down, union rec-descent +// leaf, leaf <-- insert new node, push both leaves down (!first check equality) +// leaf, fringe <-- insert new node, push this leaf and fringe down +// +// fringe, node <-- insert new node, push this fringe down, union rec-descent +// fringe, leaf <-- insert new node, push this fringe down, insert other leaf at depth+1 +// fringe, fringe <-- just overwrite value +func (n *LiteNode[V]) handleMatrixPersist(cloneFn func(V) V, thisExists bool, thisChild, otherChild any, addr uint8, depth int) int { + // Do ALL type assertions upfront - reduces line noise + var ( + thisNode, thisIsNode = thisChild.(*LiteNode[V]) + thisLeaf, thisIsLeaf = thisChild.(*LeafNode[V]) + thisFringe, thisIsFringe = thisChild.(*FringeNode[V]) + + otherNode, otherIsNode = otherChild.(*LiteNode[V]) + otherLeaf, otherIsLeaf = otherChild.(*LeafNode[V]) + otherFringe, otherIsFringe = otherChild.(*FringeNode[V]) + ) + + // just insert cloned child at this empty slot + if !thisExists { + switch { + case otherIsNode: + n.InsertChild(addr, otherNode.CloneRec(cloneFn)) + case otherIsLeaf: + n.InsertChild(addr, &LeafNode[V]{Prefix: otherLeaf.Prefix, Value: cloneFn(otherLeaf.Value)}) + case otherIsFringe: + n.InsertChild(addr, &FringeNode[V]{Value: cloneFn(otherFringe.Value)}) + default: + panic("logic error, wrong node type") + } + return 0 + } + + // Case 1: Special cases that DON'T need a new node + + // Special case: fringe + fringe -> just overwrite value + if thisIsFringe && otherIsFringe { + thisFringe.Value = cloneFn(otherFringe.Value) + return 1 + } + + // Special case: leaf + leaf with same prefix -> just overwrite value + if thisIsLeaf && otherIsLeaf && thisLeaf.Prefix == otherLeaf.Prefix { + thisLeaf.Value = cloneFn(otherLeaf.Value) + return 1 + } + + // Case 2: thisChild is already a node - clone this node, insert into it + if thisIsNode { + // CLONE the node + + // thisNode points now to cloned kid + thisNode = thisNode.CloneFlat(cloneFn) + + // replace kid with cloned thisKid + n.InsertChild(addr, thisNode) + + switch { + case otherIsNode: + return thisNode.UnionRecPersist(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if thisNode.InsertPersist(cloneFn, otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if thisNode.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong node type") + } + } + + // Case 3: All remaining cases need a new node + // (thisChild is leaf or fringe, and we didn't hit the special cases above) + + nc := new(LiteNode[V]) + + // Push existing child down into new node + switch { + case thisIsLeaf: + nc.Insert(thisLeaf.Prefix, thisLeaf.Value, depth+1) + case thisIsFringe: + nc.InsertPrefix(1, thisFringe.Value) + default: + panic("logic error, unexpected this child type") + } + + // Replace child with new node + n.InsertChild(addr, nc) + + // Now handle other child + switch { + case otherIsNode: + return nc.UnionRec(cloneFn, otherNode, depth+1) + case otherIsLeaf: + if nc.Insert(otherLeaf.Prefix, cloneFn(otherLeaf.Value), depth+1) { + return 1 + } + return 0 + case otherIsFringe: + if nc.InsertPrefix(1, cloneFn(otherFringe.Value)) { + return 1 + } + return 0 + default: + panic("logic error, wrong other node type") + } +} + +// AllRec recursively traverses the trie starting at the current node, +// applying the provided yield function to every stored prefix and value. +// +// For each route entry (prefix and value), yield is invoked. If yield returns false, +// the traversal stops immediately, and false is propagated upwards, +// enabling early termination. +// +// The function handles all prefix entries in the current node, as well as any children - +// including sub-nodes, leaf nodes with full prefixes, and fringe nodes +// representing path-compressed prefixes. IP prefix reconstruction is performed on-the-fly +// from the current path and depth. +// +// The traversal order is not defined. This implementation favors simplicity +// and runtime efficiency over consistency of iteration sequence. +func (n *LiteNode[V]) AllRec(path StridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { + var buf [256]uint8 + for _, idx := range n.Prefixes.AsSlice(&buf) { + cidr := CidrFromPath(path, depth, is4, idx) + val := n.MustGetPrefix(idx) + + // callback for this prefix and val + if !yield(cidr, val) { + // early exit + return false + } + } + + // for all children (nodes and leaves) in this node do ... + for _, addr := range n.Children.AsSlice(&buf) { + anyKid := n.MustGetChild(addr) + switch kid := anyKid.(type) { + case *LiteNode[V]: + // rec-descent with this node + path[depth] = addr + if !kid.AllRec(path, depth+1, is4, yield) { + // early exit + return false + } + case *LeafNode[V]: + // callback for this leaf + if !yield(kid.Prefix, kid.Value) { + // early exit + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// AllRecSorted recursively traverses the trie in prefix-sorted order and applies +// the given yield function to each stored prefix and value. +// +// Unlike AllRec, this implementation ensures that route entries are visited in +// canonical prefix sort order. To achieve this, +// both the prefixes and children of the current node are gathered, sorted, +// and then interleaved during traversal based on logical octet positioning. +// +// The function first sorts relevant entries by their prefix index and address value, +// using a comparison function that ranks prefixes according to their mask length and position. +// Then it walks the trie, always yielding child entries that fall before the current prefix, +// followed by the prefix itself. Remaining children are processed once all prefixes have been visited. +// +// Prefixes are reconstructed on-the-fly from the traversal path, and iteration includes all child types: +// inner nodes (recursive descent), leaf nodes, and fringe (compressed) prefixes. +// +// The order is stable and predictable, making the function suitable for use cases +// like table exports, comparisons or serialization. +// +// Parameters: +// - path: the current traversal path through the trie +// - depth: current depth in the trie (0-based) +// - is4: true for IPv4 processing, false for IPv6 +// - yield: callback function invoked for each prefix/value pair +// +// Returns false if yield function requests early termination. +func (n *LiteNode[V]) AllRecSorted(path StridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { + // get slice of all child octets, sorted by addr + var childBuf [256]uint8 + allChildAddrs := n.Children.AsSlice(&childBuf) + + // get slice of all indexes, sorted by idx + var idxBuf [256]uint8 + allIndices := n.Prefixes.AsSlice(&idxBuf) + + // sort indices in CIDR sort order + slices.SortFunc(allIndices, CmpIndexRank) + + childCursor := 0 + + // yield indices and children in CIDR sort order + for _, pfxIdx := range allIndices { + pfxOctet, _ := art.IdxToPfx(pfxIdx) + + // yield all children before idx + for j := childCursor; j < len(allChildAddrs); j++ { + childAddr := allChildAddrs[j] + + if childAddr >= pfxOctet { + break + } + + // yield the node (rec-descent) or leaf + anyKid := n.MustGetChild(childAddr) + switch kid := anyKid.(type) { + case *LiteNode[V]: + path[depth] = childAddr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, childAddr) + if !yield(fringePfx, kid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + + childCursor++ + } + + // yield the prefix for this idx + cidr := CidrFromPath(path, depth, is4, pfxIdx) + // n.prefixes.Items[i] not possible after sorting allIndices + if !yield(cidr, n.MustGetPrefix(pfxIdx)) { + return false + } + } + + // yield the rest of leaves and nodes (rec-descent) + for j := childCursor; j < len(allChildAddrs); j++ { + addr := allChildAddrs[j] + anyKid := n.MustGetChild(addr) + switch kid := anyKid.(type) { + case *LiteNode[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + if !yield(fringePfx, kid.Value) { + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// EachLookupPrefix performs a hierarchical lookup of all matching prefixes +// in the current node’s 8-bit stride-based prefix table. +// +// The function walks up the trie-internal complete binary tree (CBT), +// testing each possible prefix length mask (in decreasing order of specificity), +// and invokes the yield function for every matching entry. +// +// The given idx refers to the position for this stride's prefix and is used +// to derive a backtracking path through the CBT by repeatedly halving the index. +// At each step, if a prefix exists in the table, its corresponding CIDR is +// reconstructed and yielded. If yield returns false, traversal stops early. +// +// This function is intended for internal use during supernet traversal and +// does not descend the trie further. +func (n *LiteNode[V]) EachLookupPrefix(ip netip.Addr, depth int, pfxIdx uint8, yield func(netip.Prefix, V) bool) (ok bool) { + for ; pfxIdx > 0; pfxIdx >>= 1 { + if n.Prefixes.Test(pfxIdx) { + val := n.MustGetPrefix(pfxIdx) + + // get the CIDR back + _, pfxLen := art.IdxToPfx(pfxIdx) + cidr, _ := ip.Prefix(depth<<3 + int(pfxLen)) + + if !yield(cidr, val) { + return false + } + } + } + + return true +} + +// EachSubnet yields all prefix entries and child nodes covered by a given parent prefix, +// sorted in natural CIDR order, within the current node. +// +// The function iterates through all prefixes and children from the node’s stride tables. +// Only entries that fall within the address range defined by the parent prefix index (pfxIdx) +// are included. Matching entries are buffered, sorted, and passed through to the yield function. +// +// Child entries (nodes, leaves, fringes) that fall under the covered address range +// are processed recursively via AllRecSorted to ensure sorted traversal. +// +// This function is intended for internal use by Subnets(), and it assumes the +// current node is positioned at the point in the trie corresponding to the parent prefix. +func (n *LiteNode[V]) EachSubnet(octets []byte, depth int, is4 bool, pfxIdx uint8, yield func(netip.Prefix, V) bool) bool { + // octets as array, needed below more than once + var path StridePath + copy(path[:], octets) + + pfxFirstAddr, pfxLastAddr := art.IdxToRange(pfxIdx) + + allCoveredIndices := make([]uint8, 0, n.PrefixCount()) + + var buf [256]uint8 + for _, idx := range n.Prefixes.AsSlice(&buf) { + thisFirstAddr, thisLastAddr := art.IdxToRange(idx) + + if thisFirstAddr >= pfxFirstAddr && thisLastAddr <= pfxLastAddr { + allCoveredIndices = append(allCoveredIndices, idx) + } + } + + // sort indices in CIDR sort order + slices.SortFunc(allCoveredIndices, CmpIndexRank) + + // 2. collect all covered child addrs by prefix + + allCoveredChildAddrs := make([]uint8, 0, n.ChildCount()) + for _, addr := range n.Children.AsSlice(&buf) { + if addr >= pfxFirstAddr && addr <= pfxLastAddr { + allCoveredChildAddrs = append(allCoveredChildAddrs, addr) + } + } + + // 3. yield covered indices, path-compressed prefixes + // and children in CIDR sort order + + addrCursor := 0 + + // yield indices and children in CIDR sort order + for _, pfxIdx := range allCoveredIndices { + pfxOctet, _ := art.IdxToPfx(pfxIdx) + + // yield all children before idx + for j := addrCursor; j < len(allCoveredChildAddrs); j++ { + addr := allCoveredChildAddrs[j] + if addr >= pfxOctet { + break + } + + // yield the node or leaf? + switch kid := n.MustGetChild(addr).(type) { + case *LiteNode[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + + addrCursor++ + } + + // yield the prefix for this idx + cidr := CidrFromPath(path, depth, is4, pfxIdx) + // n.prefixes.Items[i] not possible after sorting allIndices + if !yield(cidr, n.MustGetPrefix(pfxIdx)) { + return false + } + } + + // yield the rest of leaves and nodes (rec-descent) + for _, addr := range allCoveredChildAddrs[addrCursor:] { + // yield the node or leaf? + switch kid := n.MustGetChild(addr).(type) { + case *LiteNode[V]: + path[depth] = addr + if !kid.AllRecSorted(path, depth+1, is4, yield) { + return false + } + case *LeafNode[V]: + if !yield(kid.Prefix, kid.Value) { + return false + } + case *FringeNode[V]: + fringePfx := CidrForFringe(path[:], depth, is4, addr) + // callback for this fringe + if !yield(fringePfx, kid.Value) { + // early exit + return false + } + + default: + panic("logic error, wrong node type") + } + } + + return true +} + +// Supernets yields all supernet prefixes of pfx that exist in the trie, +// in reverse order (most-specific first, least-specific last). +// +// It traverses upward from the given prefix toward the root, collecting +// matching prefixes along the path. The traversal uses a stack to yield +// results in reverse order, so that more-specific supernets appear before +// less-specific ones. +// +// The function handles all node types (internal nodes, leaves, and fringes) +// and stops early if the yield callback returns false. +// +// Parameters: +// - pfx: The prefix for which to find supernets +// - yield: Callback function invoked for each supernet prefix/value pair +// +// The yield function receives prefix/value pairs and returns false to stop +// the iteration early. +func (n *LiteNode[V]) Supernets(pfx netip.Prefix, yield func(netip.Prefix, V) bool) { + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // stack of the traversed nodes for reverse ordering of supernets + stack := [MaxTreeDepth]*LiteNode[V]{} + + // run variable, used after for loop + var depth int + var octet byte + + // find last node along this octet path +LOOP: + for depth, octet = range octets { + // stepped one past the last stride of interest; back up to last and exit + if depth > strideCount { + depth-- + break + } + // push current node on stack + stack[depth] = n + + // descend down the trie + if !n.Children.Test(octet) { + break LOOP + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *LiteNode[V]: + n = kid + continue LOOP // descend down to next trie level + + case *LeafNode[V]: + if kid.Prefix.Bits() > pfx.Bits() { + break LOOP + } + + if kid.Prefix.Overlaps(pfx) { + if !yield(kid.Prefix, kid.Value) { + // early exit + return + } + } + // end of trie along this octets path + break LOOP + + case *FringeNode[V]: + fringePfx := CidrForFringe(octets, depth, is4, octet) + if fringePfx.Bits() > pfx.Bits() { + break LOOP + } + + if fringePfx.Overlaps(pfx) { + if !yield(fringePfx, kid.Value) { + // early exit + return + } + } + // end of trie along this octets path + break LOOP + + default: + panic("logic error, wrong node type") + } + } + + // start backtracking, unwind the stack + for ; depth >= 0; depth-- { + n = stack[depth] + + // only the lastOctet may have a different prefix len + // all others are just host routes + var idx uint8 + octet = octets[depth] + // Last “octet” from prefix + // Note: For /32 and /128, depth never reaches strideCount (4/16), + if depth == strideCount { + idx = art.PfxToIdx(octet, modBits) + } else { + idx = art.OctetToIdx(octet) + } + + // micro benchmarking, skip if there is no match + if !n.Contains(idx) { + continue + } + + // yield all the matching prefixes, not just the lpm + if !n.EachLookupPrefix(ip, depth, idx, yield) { + // early exit + return + } + } +} + +// Subnets yields all subnet prefixes covered by pfx that exist in the trie, +// in CIDR sort order. +// +// It first locates the trie node corresponding to pfx, then recursively +// yields all prefixes and child entries contained within that subtree. +// The traversal uses sorted iteration to maintain canonical CIDR ordering. +// +// The function handles various node types (internal nodes, leaves, and fringes) +// and uses EachSubnet and AllRecSorted for sorted traversal of covered prefixes. +// +// Parameters: +// - pfx: The parent prefix whose subnets should be yielded +// - yield: Callback function invoked for each subnet prefix/value pair +// +// The yield function receives prefix/value pairs and returns false to stop +// the iteration early. If pfx doesn't exist in the trie, no prefixes are yielded. +func (n *LiteNode[V]) Subnets(pfx netip.Prefix, yield func(netip.Prefix, V) bool) { + // values derived from pfx + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + // find the trie node + for depth, octet := range octets { + // Last “octet” from prefix + // Note: For /32 and /128, depth never reaches strideCount (4/16), + // so those are handled below via the fringe/leaf path. + if depth == strideCount { + idx := art.PfxToIdx(octet, modBits) + n.EachSubnet(octets, depth, is4, idx, yield) + return + } + + if !n.Children.Test(octet) { + return + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *LiteNode[V]: + n = kid + continue // descend down to next trie level + + case *LeafNode[V]: + if pfx.Bits() <= kid.Prefix.Bits() && pfx.Overlaps(kid.Prefix) { + yield(kid.Prefix, kid.Value) + } + return // immediate return + + case *FringeNode[V]: + // get the LPM prefix back from ip and depth + // it's a fringe, bits are always /8, /16, /24, ... + fringePfx, _ := ip.Prefix((depth + 1) << 3) + + if pfx.Bits() <= fringePfx.Bits() && pfx.Overlaps(fringePfx) { + yield(fringePfx, kid.Value) + } + return // immediate return + + default: + panic("logic error, wrong node type") + } + } +} + +// Overlaps recursively compares two trie nodes and returns true +// if any of their prefixes or descendants overlap. +// +// The implementation checks for: +// 1. Direct overlapping prefixes on this node level +// 2. Prefixes in one node overlapping with children in the other +// 3. Matching child addresses in both nodes, which are recursively compared +// +// All 12 possible type combinations for child entries (node, leaf, fringe) are supported. +// +// The function is optimized for early exit on first match and uses heuristics to +// choose between set-based and loop-based matching for performance. +func (n *LiteNode[V]) Overlaps(o *LiteNode[V], depth int) bool { + nPfxCount := n.PrefixCount() + oPfxCount := o.PrefixCount() + + nChildCount := n.ChildCount() + oChildCount := o.ChildCount() + + // ############################## + // 1. Test if any routes overlaps + // ############################## + + // full cross check + if nPfxCount > 0 && oPfxCount > 0 { + if n.OverlapsRoutes(o) { + return true + } + } + + // #################################### + // 2. Test if routes overlaps any child + // #################################### + + // swap nodes to help chance on its way, + // if the first call to expensive overlapsChildrenIn() is already true, + // if both orders are false it doesn't help either + if nChildCount > oChildCount { + n, o = o, n + + nPfxCount = n.PrefixCount() + oPfxCount = o.PrefixCount() + + nChildCount = n.ChildCount() + oChildCount = o.ChildCount() + } + + if nPfxCount > 0 && oChildCount > 0 { + if n.OverlapsChildrenIn(o) { + return true + } + } + + // symmetric reverse + if oPfxCount > 0 && nChildCount > 0 { + if o.OverlapsChildrenIn(n) { + return true + } + } + + // ############################################ + // 3. children with same octet in nodes n and o + // ############################################ + + // stop condition, n or o have no children + if nChildCount == 0 || oChildCount == 0 { + return false + } + + // stop condition, no child with identical octet in n and o + if !n.Children.Intersects(&o.Children.BitSet256) { + return false + } + + return n.OverlapsSameChildren(o, depth) +} + +// OverlapsRoutes compares the prefix sets of two nodes (n and o). +// +// It first checks for direct bitset intersection (identical indices), +// then walks both prefix sets using the Contains method to detect if any +// of the n-prefixes is contained in o, or vice versa. +func (n *LiteNode[V]) OverlapsRoutes(o *LiteNode[V]) bool { + // some prefixes are identical, trivial overlap + if n.Prefixes.Intersects(&o.Prefixes.BitSet256) { + return true + } + + // get the lowest idx (biggest prefix) + nFirstIdx, _ := n.Prefixes.FirstSet() + oFirstIdx, _ := o.Prefixes.FirstSet() + + // start with other min value + nIdx := oFirstIdx + oIdx := nFirstIdx + + nOK := true + oOK := true + + // zip, range over n and o together to help chance on its way + for nOK || oOK { + if nOK { + // does any route in o overlap this prefix from n + if nIdx, nOK = n.Prefixes.NextSet(nIdx); nOK { + if o.Contains(nIdx) { + return true + } + + if nIdx == 255 { + // stop, don't overflow uint8! + nOK = false + } else { + nIdx++ + } + } + } + + if oOK { + // does any route in n overlap this prefix from o + if oIdx, oOK = o.Prefixes.NextSet(oIdx); oOK { + if n.Contains(oIdx) { + return true + } + + if oIdx == 255 { + // stop, don't overflow uint8! + oOK = false + } else { + oIdx++ + } + } + } + } + + return false +} + +// OverlapsChildrenIn checks whether the prefixes in node n +// overlap with any children (by address range) in node o. +// +// Uses bitset intersection or manual iteration heuristically, +// depending on prefix and child count. +// +// Bitset-based matching uses precomputed coverage tables +// to avoid per-address looping. This is critical for high fan-out nodes. +func (n *LiteNode[V]) OverlapsChildrenIn(o *LiteNode[V]) bool { + pfxCount := n.PrefixCount() + childCount := o.ChildCount() + + // heuristic: 15 is the crossover point where bitset operations become + // more efficient than iteration, determined by micro benchmarks on typical + // routing table distributions + const overlapsRangeCutoff = 15 + + doRange := childCount < overlapsRangeCutoff || pfxCount > overlapsRangeCutoff + + // do range over, not so many children and maybe too many prefixes for other algo below + var buf [256]uint8 + if doRange { + for _, addr := range o.Children.AsSlice(&buf) { + if n.Contains(art.OctetToIdx(addr)) { + return true + } + } + return false + } + + // do bitset intersection, alloted route table with child octets + // maybe too many children for range-over or not so many prefixes to + // build the alloted routing table from them + + // use allot table with prefixes as bitsets, bitsets are precalculated. + for _, idx := range n.Prefixes.AsSlice(&buf) { + if o.Children.Intersects(&allot.FringeRoutesLookupTbl[idx]) { + return true + } + } + + return false +} + +// OverlapsSameChildren compares all matching child addresses (octets) +// between node n and node o recursively. +// +// For each shared address, the corresponding child nodes (of any type) +// are compared using LiteNodeOverlapsTwoChildren, which handles all +// node/leaf/fringe combinations. +func (n *LiteNode[V]) OverlapsSameChildren(o *LiteNode[V], depth int) bool { + // intersect the child bitsets from n with o + commonChildren := n.Children.Intersection(&o.Children.BitSet256) + + for addr, ok := commonChildren.NextSet(0); ok; { + nChild := n.MustGetChild(addr) + oChild := o.MustGetChild(addr) + + if n.OverlapsTwoChildren(nChild, oChild, depth+1) { + return true + } + + if addr == 255 { + break // Prevent uint8 overflow + } + + addr, ok = commonChildren.NextSet(addr + 1) + } + return false +} + +// OverlapsPrefixAtDepth returns true if any route in the subtree rooted at this node +// overlaps with the given pfx, starting the comparison at the specified depth. +// +// This function supports structural overlap detection even in compressed or sparse +// paths within the trie, including fringe and leaf nodes. Matching is directional: +// it returns true if a route fully covers pfx, or if pfx covers an existing route. +// +// At each step, it checks for visible prefixes and children that may intersect the +// target prefix via stride-based longest-prefix test. The walk terminates early as +// soon as a structural overlap is found. +// +// This function underlies the top-level OverlapsPrefix behavior and handles details of +// trie traversal across varying prefix lengths and compression levels. +func (n *LiteNode[V]) OverlapsPrefixAtDepth(pfx netip.Prefix, depth int) bool { + ip := pfx.Addr() + pfxLen := pfx.Bits() + octets := ip.AsSlice() + strideCount, modBits := DivMod8(pfxLen) + + for ; depth < len(octets); depth++ { + if depth > strideCount { + break + } + + octet := octets[depth] + + // full octet path in node trie, check overlap with last prefix octet + if depth == strideCount { + return n.OverlapsIdx(art.PfxToIdx(octet, modBits)) + } + + // test if any route overlaps prefix´ so far + // no best match needed, forward tests without backtracking + if n.PrefixCount() != 0 && n.Contains(art.OctetToIdx(octet)) { + return true + } + + if !n.Children.Test(octet) { + return false + } + + // next child, node or leaf + switch kid := n.MustGetChild(octet).(type) { + case *LiteNode[V]: + n = kid + continue + + case *LeafNode[V]: + return kid.Prefix.Overlaps(pfx) + + case *FringeNode[V]: + return true + + default: + panic("logic error, wrong node type") + } + } + + panic("unreachable: " + pfx.String()) +} + +// OverlapsIdx returns true if the given prefix index overlaps with any entry in this node. +// +// The overlap detection considers three categories: +// +// 1. Whether any stored prefix in this node covers the requested prefix (LPM test) +// 2. Whether the requested prefix covers any stored route in the node +// 3. Whether the requested prefix overlaps with any fringe or child entry +// +// Internally, it leverages precomputed bitsets from the allotment model, +// using fast bitwise set intersections instead of explicit range comparisons. +// This enables high-performance overlap checks on a single stride level +// without descending further into the trie. +func (n *LiteNode[V]) OverlapsIdx(idx uint8) bool { + // 1. Test if any route in this node overlaps prefix? + if n.Contains(idx) { + return true + } + + // 2. Test if prefix overlaps any route in this node + if n.Prefixes.Intersects(&allot.PfxRoutesLookupTbl[idx]) { + return true + } + + // 3. Test if prefix overlaps any child in this node + return n.Children.Intersects(&allot.FringeRoutesLookupTbl[idx]) +} + +// OverlapsTwoChildren handles all 3x3 combinations of +// node kinds (node, leaf, fringe). +// +// 3x3 possible different combinations for n and o +// +// node, node --> overlaps rec descent +// node, leaf --> overlapsPrefixAtDepth +// node, fringe --> true +// +// leaf, node --> overlapsPrefixAtDepth +// leaf, leaf --> netip.Prefix.Overlaps +// leaf, fringe --> true +// +// fringe, node --> true +// fringe, leaf --> true +// fringe, fringe --> true +func (n *LiteNode[V]) OverlapsTwoChildren(nChild, oChild any, depth int) bool { + // child type detection + nNode, nIsNode := nChild.(*LiteNode[V]) + nLeaf, nIsLeaf := nChild.(*LeafNode[V]) + _, nIsFringe := nChild.(*FringeNode[V]) + + oNode, oIsNode := oChild.(*LiteNode[V]) + oLeaf, oIsLeaf := oChild.(*LeafNode[V]) + _, oIsFringe := oChild.(*FringeNode[V]) + + // Handle all 9 combinations with a single expression + switch { + // NODE cases + case nIsNode && oIsNode: + return nNode.Overlaps(oNode, depth) + case nIsNode && oIsLeaf: + return nNode.OverlapsPrefixAtDepth(oLeaf.Prefix, depth) + case nIsNode && oIsFringe: + return true + + // LEAF cases + case nIsLeaf && oIsNode: + return oNode.OverlapsPrefixAtDepth(nLeaf.Prefix, depth) + case nIsLeaf && oIsLeaf: + return oLeaf.Prefix.Overlaps(nLeaf.Prefix) + case nIsLeaf && oIsFringe: + return true + + // FRINGE cases + case nIsFringe: + return true // fringe overlaps with everything + + default: + panic("logic error, wrong node type combination") + } +} diff --git a/vendor/github.com/gaissmai/bart/internal/nodes/nodebasics.go b/vendor/github.com/gaissmai/bart/internal/nodes/nodebasics.go new file mode 100644 index 0000000..2439de1 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/nodes/nodebasics.go @@ -0,0 +1,337 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package nodes + +import ( + "cmp" + "fmt" + "net/netip" + "strconv" + "strings" + + "github.com/gaissmai/bart/internal/art" +) + +// strideLen represents the byte stride length for the multibit trie. +// Each stride processes 8 bits (1 byte) at a time. +const strideLen = 8 + +// MaxItems defines the maximum number of prefixes or children that can be stored in a single node. +// This corresponds to 256 possible values for an 8-bit stride. +const MaxItems = 256 + +// MaxTreeDepth represents the maximum depth of the trie structure. +// For IPv6 addresses, this allows up to 16 bytes of depth. +const MaxTreeDepth = 16 + +// DepthMask is used for bounds check elimination (BCE) when accessing depth-indexed arrays. +const DepthMask = MaxTreeDepth - 1 + +// StridePath represents a path through the trie, with a maximum depth of 16 octets for IPv6. +type StridePath [MaxTreeDepth]uint8 + +// TrieItem, a node has no path information about its predecessors, +// we collect this during the recursive descent. +type TrieItem[V any] struct { + // for traversing, Path/Depth/Idx is needed to get the CIDR back from the trie. + Node any // BartNode, FastNode, LiteNode + Is4 bool + Path StridePath + Depth int + Idx uint8 + + // for printing + Cidr netip.Prefix + Val V +} + +// StatsT, only used for dump, tests and benchmarks +type StatsT struct { + Prefixes int + Children int + SubNodes int + Leaves int + Fringes int +} + +type nodeType byte + +const ( + nullNode nodeType = iota // empty node + fullNode // prefixes and children or path-compressed prefixes + halfNode // no prefixes, only children and path-compressed prefixes + pathNode // only children, no prefix nor path-compressed prefixes + stopNode // no children, only prefixes or path-compressed prefixes +) + +// String implements Stringer for nodeType. +func (nt nodeType) String() string { + switch nt { + case nullNode: + return "NULL" + case fullNode: + return "FULL" + case halfNode: + return "HALF" + case pathNode: + return "PATH" + case stopNode: + return "STOP" + default: + return "unreachable" + } +} + +// addrFmt, different format strings for IPv4 and IPv6, decimal versus hex. +func addrFmt(addr byte, is4 bool) string { + if is4 { + return fmt.Sprintf("%d", addr) + } + + return fmt.Sprintf("0x%02x", addr) +} + +// ip stride path, different formats for IPv4 and IPv6, dotted decimal or hex. +// +// 127.0.0 +// 2001:0d +func ipStridePath(path StridePath, depth int, is4 bool) string { + buf := new(strings.Builder) + + if is4 { + for i, b := range path[:depth] { + if i != 0 { + buf.WriteString(".") + } + + buf.WriteString(strconv.Itoa(int(b))) + } + + return buf.String() + } + + for i, b := range path[:depth] { + if i != 0 && i%2 == 0 { + buf.WriteString(":") + } + + fmt.Fprintf(buf, "%02x", b) + } + + return buf.String() +} + +// CmpPrefix, helper function, compare func for prefix sort, +// all cidrs are already normalized +func CmpPrefix(a, b netip.Prefix) int { + if cmpAddr := a.Addr().Compare(b.Addr()); cmpAddr != 0 { + return cmpAddr + } + + return cmp.Compare(a.Bits(), b.Bits()) +} + +// LeafNode represents a path-compressed routing entry that stores both prefix and value. +// Leaf nodes are used when a prefix doesn't align with trie stride boundaries +// and needs to be stored as a compressed path to save memory. +type LeafNode[V any] struct { + Value V + Prefix netip.Prefix +} + +// NewLeafNode creates a new leaf node with the specified prefix and value. +func NewLeafNode[V any](pfx netip.Prefix, val V) *LeafNode[V] { + return &LeafNode[V]{Prefix: pfx, Value: val} +} + +// FringeNode represents a path-compressed routing entry that stores only a value. +// The prefix is implicitly defined by the node's position in the trie. +// Fringe nodes are used for prefixes that align exactly with stride boundaries +// (/8, /16, /24, etc.) to save memory by not storing redundant prefix information. +type FringeNode[V any] struct { + Value V +} + +// NewFringeNode creates a new fringe node with the specified value. +func NewFringeNode[V any](val V) *FringeNode[V] { + return &FringeNode[V]{Value: val} +} + +// IsFringe determines whether a prefix qualifies as a "FringeNode". +// Only prefixes that are stride-aligned (i.e., /8, /16, ..., /128) +// can be fringe-compressed. If these prefixes are inserted at a position +// where depth == (strideCount-1), they are treated as FringeNodes; +// at positions where depth < (strideCount-1), they are treated as LeafNodes. +// +// Example for a stride-aligned prefix like 192.168.1.0/24 (strideCount = 3, modBits = 0): +// +// depth = 3, depth == strideCount : A direct prefix with 0/0 (default route for subtrie). +// depth = 2, depth == (strideCount-1) : A path-compressed fringe. +// depth < 2, depth < (strideCount-1) : A path-compressed leaf. +func IsFringe(depth int, pfxLen int) bool { + strideCount, modBits := DivMod8(pfxLen) + return depth == strideCount-1 && modBits == 0 +} + +// CmpIndexRank, sort indexes in prefix sort order. +func CmpIndexRank(aIdx, bIdx uint8) int { + // convert idx [1..255] to prefix + aOctet, aBits := art.IdxToPfx(aIdx) + bOctet, bBits := art.IdxToPfx(bIdx) + + // cmp the prefixes, first by address and then by bits + if aOctet == bOctet { + return cmp.Compare(aBits, bBits) + } + return cmp.Compare(aOctet, bOctet) +} + +// CidrFromPath reconstructs a CIDR prefix from a stride path, depth, and index. +// The prefix is determined by the node's position in the trie and the base index +// from the ART algorithm's complete binary tree representation. +// +// Parameters: +// - path: The stride path through the trie +// - depth: Current depth in the trie +// - is4: True for IPv4 processing, false for IPv6 +// - idx: The base index from the prefix table +// +// Returns the reconstructed netip.Prefix. +func CidrFromPath(path StridePath, depth int, is4 bool, idx uint8) netip.Prefix { + depth &= DepthMask // BCE + + // retrieve the last octet and pfxLen + octet, pfxLen := art.IdxToPfx(idx) + + // set byte in path at depth with last octet + path[depth] = octet + + // canonicalize + clear(path[depth+1:]) + + // make ip addr from octets + var ip netip.Addr + if is4 { + ip = netip.AddrFrom4([4]byte(path[:4])) + } else { + ip = netip.AddrFrom16(path) + } + + // calc bits with pathLen and pfxLen + bits := depth<<3 + int(pfxLen) + + // PrefixFrom does not allocate and does not mask off the host bits of ip. + // With the clear(), the non-canonical bytes have already been removed. + return netip.PrefixFrom(ip, bits) +} + +// CidrForFringe reconstructs a CIDR prefix for a fringe node from the traversal path. +// Since fringe nodes don't store their prefix explicitly, it's derived entirely +// from the node's position in the trie and its final byte value. +// +// Parameters: +// - octets: The path of previous bytes leading up to the fringe. +// - depth: Current depth in the trie (which equals strideCount - 1). +// - is4: True for IPv4 processing, false for IPv6. +// - fringeByte: The actual 8-bit value (0-255) of the prefix at this final stride. +// +// Returns the reconstructed netip.Prefix for the fringe. +func CidrForFringe(octets []byte, depth int, is4 bool, fringeByte uint8) netip.Prefix { + depth &= DepthMask // BCE + + var path StridePath + copy(path[:], octets) + path[depth] = fringeByte + + // canonicalize, fringe bit boundaries are always a multiple of a byte + clear(path[depth+1:]) + + // make ip addr from octets + var ip netip.Addr + if is4 { + ip = netip.AddrFrom4([4]byte(path[:4])) + } else { + ip = netip.AddrFrom16(path) + } + + // it's a fringe, bits are always aligned on stride boundaries (/8, /16, /24, ...) + bits := (depth + 1) << 3 + + // PrefixFrom does not allocate and does not mask off the host bits of ip. + // With the clear(), the non-canonical bytes have already been removed. + return netip.PrefixFrom(ip, bits) +} + +// DivMod8 returns the count of full 8‑bit strides (bits/8) +// and the remaining bits in the final stride (bits%8) for pfxLen. +// +// ATTENTION: Split the IP prefixes at 8-bit borders, count from 0. +// +// /7, /15, /23, /31, ..., /127 +// +// BitPos: [0-7],[8-15],[16-23],[24-31],[32] +// BitPos: [0-7],[8-15],[16-23],[24-31],[32-39],[40-47],[48-55],[56-63],...,[120-127],[128] +// +// 0.0.0.0/0 => strideCount: 0, modBits: 0 (default route) +// 0.0.0.0/7 => strideCount: 0, modBits: 7 +// 0.0.0.0/8 => strideCount: 1, modBits: 0 (fringe candidate) +// 10.0.0.0/8 => strideCount: 1, modBits: 0 (fringe candidate) +// 10.0.0.0/22 => strideCount: 2, modBits: 6 +// 10.0.0.0/29 => strideCount: 3, modBits: 5 +// 10.0.0.0/32 => strideCount: 4, modBits: 0 (fringe candidate) +// +// ::/0 => strideCount: 0, modBits: 0 (default route) +// ::1/128 => strideCount: 16, modBits: 0 (fringe candidate) +// 2001:db8::/42 => strideCount: 5, modBits: 2 +// 2001:db8::/56 => strideCount: 7, modBits: 0 (fringe candidate) +// +// /32 and /128 prefixes are special, they never form a new node, +// At the end of the trie (IPv4: depth 4, IPv6: depth 16) they are always +// inserted as a path‑compressed fringe. +// +// We are not splitting at /8, /16, ..., because this would mean that the +// first node would have 512 prefixes, 9 bits from [0-8]. All remaining nodes +// would then only have 8 bits from [9-16], [17-24], [25..32], ... +// but the algorithm would then require a variable length bitset +// or imply a double-sized bitset. +// +// If you can commit to a fixed size of [4]uint64, then the algorithm is +// much faster due to modern CPUs. +// +// Perhaps a future Go version that supports SIMD instructions for the [4]uint64 vectors +// will make the algorithm even faster on suitable hardware. +func DivMod8(pfxLen int) (strideCount int, modBits uint8) { + // strideCount: range from 0..4 or 0..16 + // modBits: range from 0..7 + return pfxLen >> 3, uint8(pfxLen & 7) +} + +// CloneLeaf creates and returns a copy of the leafNode receiver. +// If cloneFn is nil, the value is copied directly without modification. +// Otherwise, cloneFn is applied to the value for deep cloning. +// The prefix field is always copied as is. +func (l *LeafNode[V]) CloneLeaf(cloneFn func(V) V) *LeafNode[V] { + if l == nil { + return nil + } + + if cloneFn == nil { + return &LeafNode[V]{Prefix: l.Prefix, Value: l.Value} + } + return &LeafNode[V]{Prefix: l.Prefix, Value: cloneFn(l.Value)} +} + +// CloneFringe creates and returns a copy of the FringeNode receiver. +// If cloneFn is nil, the value is copied directly without modification. +// Otherwise, cloneFn is applied to the value for deep cloning. +func (l *FringeNode[V]) CloneFringe(cloneFn func(V) V) *FringeNode[V] { + if l == nil { + return nil + } + + if cloneFn == nil { + return &FringeNode[V]{Value: l.Value} + } + return &FringeNode[V]{Value: cloneFn(l.Value)} +} diff --git a/vendor/github.com/gaissmai/bart/internal/sparse/array.go b/vendor/github.com/gaissmai/bart/internal/sparse/array.go deleted file mode 100644 index 5c32e9f..0000000 --- a/vendor/github.com/gaissmai/bart/internal/sparse/array.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 2024 Karl Gaissmaier -// SPDX-License-Identifier: MIT - -// package sparse implements a generic sparse array -// with popcount compression. -package sparse - -import ( - "github.com/gaissmai/bart/internal/bitset" -) - -// Array, a generic implementation of a sparse array -// with popcount compression and payload T. -type Array[T any] struct { - bitset.BitSet - Items []T -} - -// Get the value at i from sparse array. -// -// example: Array.Get(5) -> Array.Items[1] -// -// ⬇ -// BitSet: [0|0|1|0|0|1|0|1|...] <- 3 bits set -// Items: [*|*|*] <- len(Items) = 3 -// ⬆ -// -// BitSet.Test(5): true -// BitSet.popcount(5): 2, for interval [0,5] -// BitSet.Rank0(5): 1, equal popcount(5)-1 -func (s *Array[T]) Get(i uint) (value T, ok bool) { - if s.Test(i) { - return s.Items[s.Rank0(i)], true - } - return -} - -// MustGet, use it only after a successful test -// or the behavior is undefined, maybe it panics. -func (s *Array[T]) MustGet(i uint) T { - return s.Items[s.Rank0(i)] -} - -// UpdateAt or set the value at i via callback. The new value is returned -// and true if the value was already present. -func (s *Array[T]) UpdateAt(i uint, cb func(T, bool) T) (newValue T, wasPresent bool) { - var rank0 int - - // if already set, get current value - var oldValue T - - if wasPresent = s.Test(i); wasPresent { - rank0 = s.Rank0(i) - oldValue = s.Items[rank0] - } - - // callback function to get updated or new value - newValue = cb(oldValue, wasPresent) - - // already set, update and return value - if wasPresent { - s.Items[rank0] = newValue - - return newValue, wasPresent - } - - // new value, insert into bitset ... - s.BitSet = s.Set(i) - - // bitset has changed, recalc rank - rank0 = s.Rank0(i) - - // ... and insert value into slice - s.insertItem(rank0, newValue) - - return newValue, wasPresent -} - -// Len returns the number of items in sparse array. -func (s *Array[T]) Len() int { - return len(s.Items) -} - -// Copy returns a shallow copy of the Array. -// The elements are copied using assignment, this is no deep clone. -func (s *Array[T]) Copy() *Array[T] { - if s == nil { - return nil - } - - return &Array[T]{ - BitSet: s.BitSet.Clone(), - Items: append(s.Items[:0:0], s.Items...), - } -} - -// InsertAt a value at i into the sparse array. -// If the value already exists, overwrite it with val and return true. -func (s *Array[T]) InsertAt(i uint, value T) (exists bool) { - // slot exists, overwrite value - if s.Len() != 0 && s.Test(i) { - s.Items[s.Rank0(i)] = value - - return true - } - - // new, insert into bitset ... - s.BitSet = s.Set(i) - - // ... and slice - s.insertItem(s.Rank0(i), value) - - return false -} - -// DeleteAt a value at i from the sparse array, zeroes the tail. -func (s *Array[T]) DeleteAt(i uint) (value T, exists bool) { - if s.Len() == 0 || !s.Test(i) { - return - } - - rank0 := s.Rank0(i) - value = s.Items[rank0] - - // delete from slice - s.deleteItem(rank0) - - // delete from bitset - s.BitSet = s.Clear(i) - - return value, true -} - -// insertItem inserts the item at index i, shift the rest one pos right -// -// It panics if i is out of range. -func (s *Array[T]) insertItem(i int, item T) { - if len(s.Items) < cap(s.Items) { - s.Items = s.Items[:len(s.Items)+1] // fast resize, no alloc - } else { - var zero T - s.Items = append(s.Items, zero) // append one item, mostly enlarge cap by more than one item - } - - copy(s.Items[i+1:], s.Items[i:]) - s.Items[i] = item -} - -// deleteItem at index i, shift the rest one pos left and clears the tail item -// -// It panics if i is out of range. -func (s *Array[T]) deleteItem(i int) { - var zero T - - nl := len(s.Items) - 1 // new len - copy(s.Items[i:], s.Items[i+1:]) // overwrite item at [i] - - s.Items[nl] = zero // clear the tail item - s.Items = s.Items[:nl] // new len, keep cap is unchanged -} diff --git a/vendor/github.com/gaissmai/bart/internal/sparse/array256.go b/vendor/github.com/gaissmai/bart/internal/sparse/array256.go new file mode 100644 index 0000000..5c215cf --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/sparse/array256.go @@ -0,0 +1,220 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +// Package sparse provides a compact and efficient sparse array +// implementation for addressable key ranges from [0..255]. +// +// It is optimized for use in radix tries and lookup structures +// where only a small subset of possible keys contain actual data. +// +// Internally, an Array256 combines a fixed-size BitSet256 with +// a compact packed Items slice. The bitset tracks which key slots +// are occupied and enables fast index mapping via popcount (Rank), +// while the Items slice stores the associated payloads. +// +// Lookup, insertion, and deletion operate in O(1) time (worst-case O(n) +// only for shifting/copying in extremely full arrays). +// +// This module avoids memory allocations where possible and provides +// predictable performance even under heavy insert/delete workloads. +package sparse + +import ( + "github.com/gaissmai/bart/internal/bitset" +) + +// Array256 is a popcount-compressed sparse array for up to 256 item slots. +// +// Internally, it consists of: +// - a BitSet256, where each set bit marks a present slot (i.e., key i used) +// - a compact Items slice, which stores the payloads only for the set bits +// +// Each occupied index i ∈ [0..255] can be tested using .Test(i). +// The actual index within the Items slice is computed via .Rank(i)-1. +// +// All insert/delete operations update both the bitset and item slice +// to preserve this mapping invariant. Direct mutation of the underlying +// bitset (via Set or Clear) is forbidden and will panic. +// +// This structure allows extremely fast and compact prefix-based routing, +// highly efficient child-node containers in prefix tries, or memory-safe +// alternatives to map[uint8]T with deterministic iteration. +// +// Example layout: +// +// BitSet256: [0 1 0 0 0 1 ...] // bits 1 and 5 set +// Items: [T1, T2] // a.Items[0] ↔ key 1, a.Items[1] ↔ key 5 +type Array256[T any] struct { + bitset.BitSet256 + Items []T +} + +// Set panics. The bitset is internally coupled with Items[]. +// Use InsertAt to add or overwrite at index i. +func (a *Array256[T]) Set(uint8) { + panic("forbidden, use InsertAt") +} + +// Clear panics. The bitset is internally coupled with Items[]. +func (a *Array256[T]) Clear(uint8) { + panic("forbidden, use DeleteAt") +} + +// Get returns the value at index i and whether it exists. +// +// If the bit for i is not set, ok is false and value is the zero-value of T. +// +// example: a.Get(5) -> a.Items[1] +// +// ⬇ +// BitSet256: [0|0|1|0|0|1|0|...|1] <- 3 bits set +// Items: [*|*|*] <- len(Items) = 3 +// ⬆ +// +// BitSet256.Test(5): true +// BitSet256.Rank(5): 2 +func (a *Array256[T]) Get(i uint8) (value T, ok bool) { + if a.Test(i) { + return a.Items[a.Rank(i)-1], true + } + return +} + +// MustGet returns the value at index i without checking if it exists. +// +// Use only after ensuring i is set (via Test(i)); otherwise it may return +// an incorrect value or panic. Intended only for tight, validated loops. +func (a *Array256[T]) MustGet(i uint8) T { + return a.Items[a.Rank(i)-1] +} + +// Len returns the number of items in sparse array. +func (a *Array256[T]) Len() int { + return len(a.Items) +} + +// Copy returns a shallow copy of the Array. +// The elements are copied using assignment, this is no deep clone. +func (a *Array256[T]) Copy() *Array256[T] { + if a == nil { + return nil + } + + c := &Array256[T]{ + BitSet256: a.BitSet256, + Items: make([]T, len(a.Items)), + } + copy(c.Items, a.Items) + return c +} + +// InsertAt inserts or overwrites the value at sparse index i. +// +// If the slot at i already exists, its value is overwritten in-place and +// (rank0, true) is returned, where rank0 = Rank(i)-1 is the 0-based index +// into Items[]. +// +// If the slot is new, the bit for i is set, the value is inserted into Items[] +// at the correct packed position, and (rank0, false) is returned. +// +// rank0 can be cached by the caller to directly access Items[rank0] +// without a second Rank() call. +func (a *Array256[T]) InsertAt(i uint8, value T) (rank0 int, exists bool) { + + // slot exists, just overwrite value + if a.Test(i) { + rank0 = a.Rank(i) - 1 + a.Items[rank0] = value + return rank0, true + } + + // Since i is not set yet, Rank(i) before Set(i) is exactly + // the index where the new item should be inserted (equivalent to Rank(i)-1 after Set(i)). + rank0 = a.Rank(i) + + // new, insert into bitset ... + a.BitSet256.Set(i) + + // ... and insert value into slice + a.insertItem(rank0, value) + + return rank0, false +} + +// DeleteAt removes the value at index i from the sparse array, +// shifting remaining items down in the slice and clearing the bit. +// +// If the entry exists, it is returned together with true. +// If i is not present, the zero value and false are returned. +func (a *Array256[T]) DeleteAt(i uint8) (value T, exists bool) { + if a.Len() == 0 || !a.Test(i) { + return value, exists + } + + rank0 := a.Rank(i) - 1 + value = a.Items[rank0] + + // delete from slice + a.deleteItem(rank0) + + // delete from bitset + a.BitSet256.Clear(i) + + return value, true +} + +// insertItem inserts a new element at the given index position i in the Items slice, +// shifting all following elements one position to the right to make space. +// +// This method must be called with the correct insertion index - that is, +// the rank-0 value of the corresponding bit index i in BitSet256 (calculated before Set(i)). +// +// The slice will be extended by one element. If the capacity allows, this is done +// without reallocation (fast path); otherwise slice growth occurs (slow path). +// +// Example (inserting at rank0 == 2): +// +// Items before: [A B C D] +// After insertItem(2, X): [A B X C D] +// +// Panics if i is out of range (i < 0 or i > len(Items)). +func (a *Array256[T]) insertItem(i int, item T) { + if len(a.Items) < cap(a.Items) { + a.Items = a.Items[:len(a.Items)+1] // fast resize, no alloc + } else { + var zero T + a.Items = append(a.Items, zero) // append one item, mostly enlarge cap by more than one item + } + + _ = a.Items[i] // BCE + copy(a.Items[i+1:], a.Items[i:]) // shift one slot right, starting at [i] + a.Items[i] = item // insert new item at [i] +} + +// deleteItem removes the item at index i from the Items slice, +// shifting all subsequent items one position to the left, +// and clearing the final (now duplicate) slot. +// +// This is used to remove Items[i] in response to a BitSet256.Clear(i) +// operation, where i is guaranteed to be set and valid. +// +// Example (deleting rank0 == 1): +// +// Items before: [A B C D] +// After deleteItem(1): [A C D] +// +// The tail item is explicitly cleared (assigned the zero-value of T) +// to avoid holding references (important for GC with pointer types). +// +// Panics if i is out of range (i < 0 or i >= len(Items)). +func (a *Array256[T]) deleteItem(i int) { + var zero T + + _ = a.Items[i] // BCE + copy(a.Items[i:], a.Items[i+1:]) // shift left, overwrite item at [i] + + nl := len(a.Items) - 1 // new len + + a.Items[nl] = zero // clear the tail item + a.Items = a.Items[:nl] // new len, cap is unchanged +} diff --git a/vendor/github.com/gaissmai/bart/internal/tests/golden/table.go b/vendor/github.com/gaissmai/bart/internal/tests/golden/table.go new file mode 100644 index 0000000..727b3a9 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/tests/golden/table.go @@ -0,0 +1,207 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package golden + +import ( + "cmp" + "fmt" + "net/netip" + "slices" +) + +// Table is a simple and slow route table, implemented as a slice of prefixes +// and values as a golden reference for bart. +type Table[V any] []TableItem[V] + +type TableItem[V any] struct { + Pfx netip.Prefix + Val V +} + +func (g TableItem[V]) String() string { + return fmt.Sprintf("(%s, %v)", g.Pfx, g.Val) +} + +func (t *Table[V]) Insert(pfx netip.Prefix, val V) { + pfx = pfx.Masked() + for i, item := range *t { + if item.Pfx == pfx { + (*t)[i].Val = val // de-dupe + return + } + } + *t = append(*t, TableItem[V]{pfx, val}) +} + +func (t *Table[V]) Delete(pfx netip.Prefix) (exists bool) { + pfx = pfx.Masked() + + for i, item := range *t { + if item.Pfx == pfx { + *t = slices.Delete(*t, i, i+1) + return true + } + } + return false +} + +func (t Table[V]) AllSorted() []netip.Prefix { + var result []netip.Prefix + + for _, item := range t { + result = append(result, item.Pfx) + } + slices.SortFunc(result, cmpPrefix) + return result +} + +func (t Table[V]) Get(pfx netip.Prefix) (val V, ok bool) { + pfx = pfx.Masked() + for _, item := range t { + if item.Pfx == pfx { + return item.Val, true + } + } + return val, false +} + +func (t *Table[V]) Update(pfx netip.Prefix, cb func(V, bool) V) (val V) { + pfx = pfx.Masked() + for i, item := range *t { + if item.Pfx == pfx { + // update val + val = cb(item.Val, true) + (*t)[i].Val = val + return val + } + } + // new val + val = cb(val, false) + + *t = append(*t, TableItem[V]{pfx, val}) + return val +} + +func (ta *Table[V]) Union(tb *Table[V]) { + for _, bItem := range *tb { + var match bool + for i, aItem := range *ta { + if aItem.Pfx == bItem.Pfx { + (*ta)[i] = bItem + match = true + break + } + } + if !match { + *ta = append(*ta, bItem) + } + } +} + +func (t Table[V]) Lookup(addr netip.Addr) (val V, ok bool) { + bestLen := -1 + + for _, item := range t { + if item.Pfx.Contains(addr) && item.Pfx.Bits() > bestLen { + val = item.Val + ok = true + bestLen = item.Pfx.Bits() + } + } + return val, ok +} + +func (t Table[V]) LookupPrefix(pfx netip.Prefix) (val V, ok bool) { + pfx = pfx.Masked() + bestLen := -1 + + for _, item := range t { + if item.Pfx.Overlaps(pfx) && item.Pfx.Bits() <= pfx.Bits() && item.Pfx.Bits() > bestLen { + val = item.Val + ok = true + bestLen = item.Pfx.Bits() + } + } + return val, ok +} + +func (t Table[V]) LookupPrefixLPM(pfx netip.Prefix) (lpm netip.Prefix, val V, ok bool) { + pfx = pfx.Masked() + bestLen := -1 + + for _, item := range t { + if item.Pfx.Overlaps(pfx) && item.Pfx.Bits() <= pfx.Bits() && item.Pfx.Bits() > bestLen { + val = item.Val + lpm = item.Pfx + ok = true + bestLen = item.Pfx.Bits() + } + } + return lpm, val, ok +} + +func (t Table[V]) Subnets(pfx netip.Prefix) []netip.Prefix { + pfx = pfx.Masked() + var result []netip.Prefix + + for _, item := range t { + if pfx.Overlaps(item.Pfx) && pfx.Bits() <= item.Pfx.Bits() { + result = append(result, item.Pfx) + } + } + slices.SortFunc(result, cmpPrefix) + return result +} + +func (t Table[V]) Supernets(pfx netip.Prefix) []netip.Prefix { + pfx = pfx.Masked() + var result []netip.Prefix + + for _, item := range t { + if item.Pfx.Overlaps(pfx) && item.Pfx.Bits() <= pfx.Bits() { + result = append(result, item.Pfx) + } + } + slices.SortFunc(result, cmpPrefix) + slices.Reverse(result) + return result +} + +func (t Table[V]) OverlapsPrefix(pfx netip.Prefix) bool { + pfx = pfx.Masked() + for _, p := range t { + if p.Pfx.Overlaps(pfx) { + return true + } + } + return false +} + +func (ta *Table[V]) Overlaps(tb *Table[V]) bool { + for _, aItem := range *ta { + for _, bItem := range *tb { + if aItem.Pfx.Overlaps(bItem.Pfx) { + return true + } + } + } + return false +} + +// Sort, inplace by netip.Prefix, all prefixes are in normalized form +func (t *Table[V]) Sort() { + slices.SortFunc(*t, func(a, b TableItem[V]) int { + return cmpPrefix(a.Pfx, b.Pfx) + }) +} + +// cmpPrefix, helper function, compare func for prefix sort, +// all cidrs are already normalized +func cmpPrefix(a, b netip.Prefix) int { + if cmpAddr := a.Addr().Compare(b.Addr()); cmpAddr != 0 { + return cmpAddr + } + + return cmp.Compare(a.Bits(), b.Bits()) +} diff --git a/vendor/github.com/gaissmai/bart/internal/tests/random/random.go b/vendor/github.com/gaissmai/bart/internal/tests/random/random.go new file mode 100644 index 0000000..7ee67a6 --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/tests/random/random.go @@ -0,0 +1,129 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package random + +import ( + "fmt" + "math/rand/v2" + "net/netip" +) + +// mpp is a abbreviation and panics on non masked prefixes. +// +//nolint:gochecknoglobals +var mpp = func(s string) netip.Prefix { + pfx := netip.MustParsePrefix(s) + if pfx == pfx.Masked() { + return pfx + } + panic(fmt.Sprintf("%s is not canonicalized as %s", s, pfx.Masked())) +} + +// Prefix returns a randomly generated prefix +func Prefix(prng *rand.Rand) netip.Prefix { + if prng.IntN(2) == 1 { + return Prefix4(prng) + } + return Prefix6(prng) +} + +func Prefix4(prng *rand.Rand) netip.Prefix { + bits := prng.IntN(33) + return netip.PrefixFrom(IP4(prng), bits).Masked() +} + +func Prefix6(prng *rand.Rand) netip.Prefix { + bits := prng.IntN(129) + return netip.PrefixFrom(IP6(prng), bits).Masked() +} + +func IP4(prng *rand.Rand) netip.Addr { + var b [4]byte + for i := range b { + //nolint:gosec // G115: integer overflow conversion uint -> byte + b[i] = byte(prng.UintN(256)) + } + return netip.AddrFrom4(b) +} + +func IP6(prng *rand.Rand) netip.Addr { + var b [16]byte + for i := range b { + //nolint:gosec // G115: integer overflow conversion uint -> byte + b[i] = byte(prng.UintN(256)) + } + return netip.AddrFrom16(b) +} + +func IP(prng *rand.Rand) netip.Addr { + if prng.IntN(2) == 1 { + return IP4(prng) + } + return IP6(prng) +} + +func RealWorldPrefixes4(prng *rand.Rand, n int) []netip.Prefix { + set := make(map[netip.Prefix]struct{}) + pfxs := make([]netip.Prefix, 0, n) + + for len(set) < n { + pfx := Prefix4(prng) + + // skip too small or too big masks + if pfx.Bits() < 8 || pfx.Bits() > 28 { + continue + } + + // skip reserved/experimental ranges (e.g., 240.0.0.0/8) + if pfx.Overlaps(mpp("240.0.0.0/8")) { + continue + } + + if _, ok := set[pfx]; !ok { + set[pfx] = struct{}{} + pfxs = append(pfxs, pfx) + } + } + return pfxs +} + +func RealWorldPrefixes6(prng *rand.Rand, n int) []netip.Prefix { + set := make(map[netip.Prefix]struct{}) + pfxs := make([]netip.Prefix, 0, n) + + for len(set) < n { + pfx := Prefix6(prng) + + // skip too small or too big masks + if pfx.Bits() < 16 || pfx.Bits() > 56 { + continue + } + + // skip non global routes seen in the real world + if !pfx.Overlaps(mpp("2000::/3")) { + continue + } + if pfx.Addr().Compare(mpp("2c0f::/16").Addr()) == 1 { + continue + } + + if _, ok := set[pfx]; !ok { + set[pfx] = struct{}{} + pfxs = append(pfxs, pfx) + } + } + return pfxs +} + +func RealWorldPrefixes(prng *rand.Rand, n int) []netip.Prefix { + pfxs := make([]netip.Prefix, 0, n) + pfxs = append(pfxs, RealWorldPrefixes4(prng, n/2)...) + pfxs = append(pfxs, RealWorldPrefixes6(prng, n-len(pfxs))...) + + prng.Shuffle(len(pfxs), func(i, j int) { + pfxs[i], pfxs[j] = pfxs[j], pfxs[i] + }) + + return pfxs +} diff --git a/vendor/github.com/gaissmai/bart/internal/value/value.go b/vendor/github.com/gaissmai/bart/internal/value/value.go new file mode 100644 index 0000000..9ebe1ae --- /dev/null +++ b/vendor/github.com/gaissmai/bart/internal/value/value.go @@ -0,0 +1,77 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +// Package value provides runtime utilities for working with generic type +// parameters as payload values in bart data structures. +// +// The package offers three main categories of utilities: +// +// # V as type struct{} Detection +// +// IsEmptyStruct[V] detects whether a type parameter V is a `struct{}`. These +// types carry no information in their values. Omitting them from dumps +// and prints reduces line noise and improves readability. +// +// # Value Equality +// +// The [Equal] function enables custom equality logic for payload values. +// When V implements an `Equal(V) bool` method, [Equal] uses that implementation, +// avoiding the potentially expensive [reflect.DeepEqual] fallback. +// +// # Value Cloning +// +// The [CloneFnFactory] supports copying of payload values for persistent +// operations. When V implements a `Clone() V` method, +// bart methods like InsertPersist, DeletePersist, and UnionPersist use the +// generated clone function to create independent copies. +// +// This is an internal package used by the bart data structure implementation. +package value + +// IsEmptyStruct reports whether type V is the unnamed empty struct type `struct{}`. +func IsEmptyStruct[V any]() bool { + var zero V + _, ok := any(zero).(struct{}) + return ok +} + +// Equal compares two values of type V for equality. +// +// If V implements an `Equal(V) bool` method, its custom equality logic is used. +// Otherwise, values are compared directly using the == operator. +// +// If V is not comparable at runtime (such as a slice or map without an Equal +// method), a runtime panic will occur. +// +// Note: If V implements Equal(V) bool with a pointer receiver, the Equal +// method should handle nil receivers gracefully. +func Equal[V any](v1, v2 V) bool { + if eq, ok := any(v1).(interface{ Equal(V) bool }); ok { + return eq.Equal(v2) + } + + return any(v1) == any(v2) +} + +// CloneFnFactory returns a function that takes a value of type V and returns +// a copy by calling its `Clone` method. +// +// If V does not implement a `Clone() V` method, it returns nil. +// +// Note: If V implements `Clone() V` with a pointer receiver, the `Clone` +// method should handle nil receivers gracefully. +func CloneFnFactory[V any]() func(V) V { + var zero V + + // Safely check if V implements the clone method using an inline interface. + if _, ok := any(zero).(interface{ Clone() V }); ok { + // Return an anonymous closure directly. + // Since we already proved V implements the interface above, + // the direct type assertion here is guaranteed to succeed. + return func(val V) V { + return any(val).(interface{ Clone() V }).Clone() + } + } + + return nil +} diff --git a/vendor/github.com/gaissmai/bart/jsonify.go b/vendor/github.com/gaissmai/bart/jsonify.go deleted file mode 100644 index 8e37038..0000000 --- a/vendor/github.com/gaissmai/bart/jsonify.go +++ /dev/null @@ -1,79 +0,0 @@ -package bart - -// Copyright (c) 2024 Karl Gaissmaier -// SPDX-License-Identifier: MIT - -import ( - "encoding/json" - "net/netip" - "slices" -) - -// DumpListNode contains CIDR, value and list of subnets (tree childrens). -type DumpListNode[V any] struct { - CIDR netip.Prefix `json:"cidr"` - Value V `json:"value"` - Subnets []DumpListNode[V] `json:"subnets,omitempty"` -} - -// MarshalJSON dumps the table into two sorted lists: for ipv4 and ipv6. -// Every root and subnet is an array, not a map, because the order matters. -func (t *Table[V]) MarshalJSON() ([]byte, error) { - if t == nil { - return nil, nil - } - - result := struct { - Ipv4 []DumpListNode[V] `json:"ipv4,omitempty"` - Ipv6 []DumpListNode[V] `json:"ipv6,omitempty"` - }{ - Ipv4: t.DumpList4(), - Ipv6: t.DumpList6(), - } - - buf, err := json.Marshal(result) - if err != nil { - return nil, err - } - - return buf, nil -} - -// DumpList4 dumps the ipv4 tree into a list of roots and their subnets. -// It can be used to analyze the tree or build custom json representation. -func (t *Table[V]) DumpList4() []DumpListNode[V] { - if t == nil { - return nil - } - return t.root4.dumpListRec(0, stridePath{}, 0, true) -} - -// DumpList6 dumps the ipv6 tree into a list of roots and their subnets. -// It can be used to analyze the tree or build custom json representation. -func (t *Table[V]) DumpList6() []DumpListNode[V] { - if t == nil { - return nil - } - return t.root6.dumpListRec(0, stridePath{}, 0, false) -} - -func (n *node[V]) dumpListRec(parentIdx uint, path stridePath, depth int, is4 bool) []DumpListNode[V] { - // recursion stop condition - if n == nil { - return nil - } - - directKids := n.getKidsRec(parentIdx, path, depth, is4) - slices.SortFunc(directKids, cmpKidByPrefix[V]) - - nodes := make([]DumpListNode[V], 0, len(directKids)) - for _, kid := range directKids { - nodes = append(nodes, DumpListNode[V]{ - CIDR: kid.cidr, - Value: kid.val, - Subnets: kid.n.dumpListRec(kid.idx, kid.path, kid.depth, is4), - }) - } - - return nodes -} diff --git a/vendor/github.com/gaissmai/bart/lite.go b/vendor/github.com/gaissmai/bart/lite.go new file mode 100644 index 0000000..92ff17a --- /dev/null +++ b/vendor/github.com/gaissmai/bart/lite.go @@ -0,0 +1,680 @@ +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package bart + +import ( + "io" + "iter" + "net/netip" + "sync" + + "github.com/gaissmai/bart/internal/art" + "github.com/gaissmai/bart/internal/lpm" + "github.com/gaissmai/bart/internal/nodes" +) + +// Lite follows the BART design but with no payload. +// It is ideal for simple IP ACLs (access-control-lists) with plain +// true/false results with the smallest memory consumption. +// +// The zero value is ready to use. +// +// A Lite table must not be copied by value; always pass by pointer. +// Nil pointers as receivers or arguments are forbidden and will panic. +// +// Performance note: Do not pass IPv4-in-IPv6 addresses (e.g., ::ffff:192.0.2.1) +// as input. The methods do not perform automatic unmapping to avoid unnecessary +// overhead for the common case where native addresses are used. +// Users should unmap IPv4-in-IPv6 addresses to their native IPv4 form +// (e.g., 192.0.2.1) before calling these methods. +type Lite struct { + liteTable[struct{}] +} + +// BEGIN OF liteTable WRAPPER + +// Get performs an exact-prefix lookup and returns whether the exact +// prefix exists. The prefix is canonicalized (Masked) before lookup. +// +// This is an exact-match operation (no LPM). The prefix must match exactly +// in both address and prefix length to be found. +// If pfx is valid and exists, true is returned, otherwise false. +// +// For longest-prefix-match (LPM) lookups, use Contains(ip), Lookup(ip), +// LookupPrefix(pfx) or LookupPrefixLPM(pfx) instead. +func (l *Lite) Get(pfx netip.Prefix) bool { + _, ok := l.liteTable.Get(pfx) + return ok +} + +// Lookup performs a longest-prefix-match (LPM) for addr. +// +// Note: Lite stores no payload values, so this method is rarely useful. +// Prefer Contains(addr) to check whether any prefix matches the address. +// For exact prefix existence use Get(pfx). For prefix-based LPM use +// LookupPrefix or LookupPrefixLPM. +// +// Returns true if any prefix matches addr, otherwise false. +func (l *Lite) Lookup(ip netip.Addr) bool { + return l.Contains(ip) +} + +// LookupPrefix performs a longest prefix match lookup for any address within +// the given prefix. +// +// Returns true if a matching prefix is found, otherwise false. +func (l *Lite) LookupPrefix(pfx netip.Prefix) bool { + _, ok := l.lookupPrefixLPM(pfx, false) + return ok +} + +// LookupPrefixLPM performs a longest prefix match lookup for any address within +// the given prefix. It finds the most specific routing table entry that would +// match any address in the provided prefix range. +// +// This is functionally identical to LookupPrefix but returns the +// matching LPM prefix itself. +// +// This method is slower than LookupPrefix and should only be used if the +// matching lpm entry is also required for other reasons. +// +// Returns the matching prefix and true if found, otherwise the zero value and false. +func (l *Lite) LookupPrefixLPM(pfx netip.Prefix) (lpmPfx netip.Prefix, ok bool) { + return l.lookupPrefixLPM(pfx, true) +} + +// Insert adds a prefix to the routing table. +// If the prefix already exists, it's a no-op; otherwise a new entry is created. +// Invalid prefixes are silently ignored. +// +// The prefix is automatically canonicalized using pfx.Masked() to ensure +// consistent behavior regardless of host bits in the input. +func (l *Lite) Insert(pfx netip.Prefix) { + l.liteTable.Insert(pfx, struct{}{}) +} + +// InsertPersist is similar to Insert but the receiver isn't modified. +// +// All nodes touched during insert are cloned and a new *Lite is returned. +// This is not a full [Lite.Clone], all untouched nodes are still referenced +// from both Tables. +// +// This is orders of magnitude slower than Insert, +// typically taking μsec instead of nsec. +// +// The bulk table load could be done with [Lite.Insert] and then you can +// use [Lite.InsertPersist], [Lite.ModifyPersist] and [Lite.DeletePersist] +// for further lock-free ops. +func (l *Lite) InsertPersist(pfx netip.Prefix) *Lite { + lp := l.liteTable.InsertPersist(pfx, struct{}{}) + //nolint:govet // copy of *lp is here by intention + return &Lite{*lp} +} + +// DeletePersist is similar to Delete but does not modify the receiver. +// +// It performs a copy-on-write delete operation, cloning all nodes +// touched during deletion and returning a new *Lite reflecting the change. +// +// If the prefix is invalid or doesn't exist, the original table is +// returned unchanged. +// +// Due to cloning overhead this is significantly slower than Delete, +// typically taking μsec instead of nsec. +func (l *Lite) DeletePersist(pfx netip.Prefix) *Lite { + lp := l.liteTable.DeletePersist(pfx) + if lp == &l.liteTable { + // pfx is invalid or didn't exist + return l + } + + //nolint:govet // copy of *lp is here by intention + return &Lite{*lp} +} + +// Modify applies an insert, update, or delete for the given prefix. +// The prefix is canonicalized (Masked) internally before the operation. +// The operation is determined by the callback function, which is called with: +// +// true: the prefix is in table +// false: the prefix is not in table +// +// The callback returns: +// +// true: delete the entry +// false: insert or update +// +// Summary of callback semantics: +// +// | input | return | op | +// --------------------------- +// | false | true | no-op | +// | false | false | insert | +// | true | false | update | +// | true | true | delete | +// --------------------------- +func (l *Lite) Modify(pfx netip.Prefix, cb func(exists bool) (del bool)) { + // Adapt the callback to work with liteTable's signature + adaptedCb := func(_ struct{}, exists bool) (_ struct{}, del bool) { + return struct{}{}, cb(exists) + } + + l.liteTable.Modify(pfx, adaptedCb) +} + +// ModifyPersist is similar to Modify but the receiver isn't modified and +// a new *Lite is returned. +func (l *Lite) ModifyPersist(pfx netip.Prefix, cb func(exists bool) (del bool)) *Lite { + // wrap callback to match the signature of liteTable.ModifyPersist + cbWrapper := func(_ struct{}, exists bool) (_ struct{}, del bool) { + return struct{}{}, cb(exists) + } + + lp := l.liteTable.ModifyPersist(pfx, cbWrapper) + //nolint:govet // copy of *lp is here by intention + return &Lite{*lp} +} + +// dropSeq2 converts a Seq2[netip.Prefix, V] into a Seq[netip.Prefix] by discarding the value. +func dropSeq2[V any](seq2 iter.Seq2[netip.Prefix, V]) iter.Seq[netip.Prefix] { + return func(yield func(netip.Prefix) bool) { + seq2(func(p netip.Prefix, _ V) bool { + return yield(p) + }) + } +} + +// Clone returns a copy of the routing table. +func (l *Lite) Clone() *Lite { + return &Lite{*l.liteTable.Clone()} +} + +// Union merges another routing table into the receiver table, modifying it in-place. +// +// All prefixes from the other table (o) are inserted into the receiver. +func (l *Lite) Union(o *Lite) { + l.liteTable.Union(&o.liteTable) +} + +// UnionPersist is similar to [Union] but the receiver isn't modified. +// +// All nodes touched during union are cloned and a new *Lite is returned. +// If o is empty, no nodes are touched and the receiver may be +// returned unchanged. +func (l *Lite) UnionPersist(o *Lite) *Lite { + lp := l.liteTable.UnionPersist(&o.liteTable) + if lp == &l.liteTable { + return l + } + //nolint:govet // copy of *lp is here by intention + return &Lite{*lp} +} + +// All returns an iterator over all prefixes in the table. +// +// The iteration order is unspecified and may vary between calls; for a stable order, +// use [Lite.AllSorted]. +// +// IMPORTANT: Modifying the table during iteration is not allowed, +// as this would interfere with the internal traversal and may corrupt or +// prematurely terminate the iteration. +func (l *Lite) All() iter.Seq[netip.Prefix] { + return dropSeq2(l.liteTable.All()) +} + +// All4 is like [Lite.All] but only for the v4 routing table. +func (l *Lite) All4() iter.Seq[netip.Prefix] { + return dropSeq2(l.liteTable.All4()) +} + +// All6 is like [Lite.All] but only for the v6 routing table. +func (l *Lite) All6() iter.Seq[netip.Prefix] { + return dropSeq2(l.liteTable.All6()) +} + +// AllSorted is like [Lite.All] but the iteration is ordered in canonical +// CIDR prefix sort order. +func (l *Lite) AllSorted() iter.Seq[netip.Prefix] { + return dropSeq2(l.liteTable.AllSorted()) +} + +// AllSorted4 is like [Lite.AllSorted] but only for the v4 routing table. +func (l *Lite) AllSorted4() iter.Seq[netip.Prefix] { + return dropSeq2(l.liteTable.AllSorted4()) +} + +// AllSorted6 is like [Lite.AllSorted] but only for the v6 routing table. +func (l *Lite) AllSorted6() iter.Seq[netip.Prefix] { + return dropSeq2(l.liteTable.AllSorted6()) +} + +// Subnets returns an iterator over all subnets of the given prefix +// in natural CIDR sort order. This includes prefixes of the same length +// (exact match) and longer (more specific) prefixes that are contained +// within the given prefix. +// +// Example: +// +// for sub := range table.Subnets(netip.MustParsePrefix("10.0.0.0/8")) { +// fmt.Println("Covered:", sub) +// } +// +// The iteration can be stopped early by breaking from the range loop. +// Returns an empty iterator if the prefix is invalid. +func (l *Lite) Subnets(pfx netip.Prefix) iter.Seq[netip.Prefix] { + return dropSeq2(l.liteTable.Subnets(pfx)) +} + +// Supernets returns an iterator over all supernet routes that cover the given prefix pfx. +// +// The traversal searches both exact-length and shorter (less specific) prefixes that +// overlap or include pfx. Starting from the most specific position in the trie, +// it walks upward through parent nodes and yields any matching entries found at each level. +// +// The iteration order is reverse-CIDR: from longest prefix match (LPM) towards +// least-specific routes. +// +// The search is protocol-specific (IPv4 or IPv6) and stops immediately if the yield +// function returns false. If pfx is invalid, the function silently returns. +// +// This can be used to enumerate all covering supernet routes in routing-based +// policy engines, diagnostics tools, or fallback resolution logic. +// +// Example: +// +// for supernet := range table.Supernets(netip.MustParsePrefix("192.0.2.128/25")) { +// fmt.Println("Matched covering route:", supernet) +// } +func (l *Lite) Supernets(pfx netip.Prefix) iter.Seq[netip.Prefix] { + return dropSeq2(l.liteTable.Supernets(pfx)) +} + +// Overlaps reports whether any route in the receiver table overlaps +// with a route in the other table, in either direction. +// +// The overlap check is bidirectional: it returns true if any IP prefix +// in the receiver is covered by the other table, or vice versa. +// This includes partial overlaps, exact matches, and supernet/subnet relationships. +// +// Both IPv4 and IPv6 route trees are compared independently. If either +// tree has overlapping routes, the function returns true. +// +// This is useful for conflict detection, policy enforcement, +// or validating mutually exclusive routing domains. +// +// It is intentionally not nil-receiver safe: calling with a nil +// receiver will panic by design. +func (l *Lite) Overlaps(o *Lite) bool { + return l.liteTable.Overlaps(&o.liteTable) +} + +// Overlaps4 is like [Lite.Overlaps] but for the v4 routing table only. +func (l *Lite) Overlaps4(o *Lite) bool { + return l.liteTable.Overlaps4(&o.liteTable) +} + +// Overlaps6 is like [Lite.Overlaps] but for the v6 routing table only. +func (l *Lite) Overlaps6(o *Lite) bool { + return l.liteTable.Overlaps6(&o.liteTable) +} + +// Equal checks whether two tables are structurally and semantically equal. +// It ensures both trees (IPv4-based and IPv6-based) have the same sizes and +// recursively compares their root nodes. +// +// Note: Lite has no payload values, so this only checks structural equality. +func (l *Lite) Equal(o *Lite) bool { + return l.liteTable.Equal(&o.liteTable) +} + +// DumpList4 dumps the ipv4 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build the text or JSON serialization. +func (l *Lite) DumpList4() []DumpListNode[struct{}] { + return l.liteTable.DumpList4() +} + +// DumpList6 dumps the ipv6 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build custom JSON representation. +func (l *Lite) DumpList6() []DumpListNode[struct{}] { + return l.liteTable.DumpList6() +} + +// Fprint writes a hierarchical tree diagram of the ordered CIDRs +// with default formatted payload V to w. +// +// The order from top to bottom is in ascending order of the prefix address +// and the subtree structure is determined by the CIDRs coverage. +// +// ▼ +// ├─ 10.0.0.0/8 (V) +// │ ├─ 10.0.0.0/24 (V) +// │ └─ 10.0.1.0/24 (V) +// ├─ 127.0.0.0/8 (V) +// │ └─ 127.0.0.1/32 (V) +// ├─ 169.254.0.0/16 (V) +// ├─ 172.16.0.0/12 (V) +// └─ 192.168.0.0/16 (V) +// └─ 192.168.1.0/24 (V) +// ▼ +// └─ ::/0 (V) +// ├─ ::1/128 (V) +// ├─ 2000::/3 (V) +// │ └─ 2001:db8::/32 (V) +// └─ fe80::/10 (V) +func (l *Lite) Fprint(w io.Writer) error { + return l.liteTable.Fprint(w) +} + +// MarshalJSON dumps the table into two sorted lists: for ipv4 and ipv6. +// Every root and subnet is an array, not a map, because the order matters. +func (l *Lite) MarshalJSON() ([]byte, error) { + return l.liteTable.MarshalJSON() +} + +// MarshalText implements the [encoding.TextMarshaler] interface, +// just a wrapper for [liteTable.Fprint]. +func (l *Lite) MarshalText() ([]byte, error) { + return l.liteTable.MarshalText() +} + +// END OF liteTable WRAPPER + +// liteTable follows the BART design but with no payload. +// It is ideal for simple IP ACLs (access-control-lists) with plain +// true/false results with the smallest memory consumption. +// +// Performance note: Do not pass IPv4-in-IPv6 addresses (e.g., ::ffff:192.0.2.1) +// as input. The methods do not perform automatic unmapping to avoid unnecessary +// overhead for the common case where native addresses are used. +// Users should unmap IPv4-in-IPv6 addresses to their native IPv4 form +// (e.g., 192.0.2.1) before calling these methods. +type liteTable[V any] struct { + // used by -copylocks checker from `go vet`. + _ [0]sync.Mutex + + root4 nodes.LiteNode[V] + root6 nodes.LiteNode[V] + + // the number of prefixes in the routing table + size4 int + size6 int +} + +// rootNodeByVersion, root node getter for ip version. +func (l *liteTable[V]) rootNodeByVersion(is4 bool) *nodes.LiteNode[V] { + if is4 { + return &l.root4 + } + return &l.root6 +} + +// Insert adds or updates a prefix-value pair in the routing table. +// If the prefix already exists, its value is updated; otherwise a new entry is created. +// Invalid prefixes are silently ignored. +// +// The prefix is automatically canonicalized using pfx.Masked() to ensure +// consistent behavior regardless of host bits in the input. +func (l *liteTable[V]) Insert(pfx netip.Prefix, val V) { + l.insert(pfx, val) +} + +// InsertPersist is similar to Insert but the receiver isn't modified. +// +// All nodes touched during insert are cloned and a new liteTable is returned. +// This is not a full [liteTable.Clone], all untouched nodes are still referenced +// from both Tables. +// +// Due to cloning overhead this is significantly slower than Insert, +// typically taking μsec instead of nsec. +func (l *liteTable[V]) InsertPersist(pfx netip.Prefix, val V) *liteTable[V] { + return l.insertPersist(pfx, val) +} + +// Modify applies an insert, update, or delete operation for the value +// associated with the given prefix. The supplied callback decides the +// operation: it is called with the current value (or zero if not found) +// and a boolean indicating whether the prefix exists. The callback must +// return a new value and a delete flag: del == false inserts or updates, +// del == true deletes the entry if it exists (otherwise no-op). +// +// The operation is determined by the callback function, which is called with: +// +// val: the current value (or zero value if not found) +// found: true if the prefix currently exists, false otherwise +// +// The callback returns: +// +// val: the new value to insert or update (ignored if del == true) +// del: true to delete the entry, false to insert or update +// +// Summary of callback semantics: +// +// | cb-input | cb-return | Ops | +// ------------------------------------- -------- +// | (zero, false) | (_, true) | no-op | +// | (zero, false) | (newVal, false) | insert | +// | (oldVal, true) | (newVal, false) | update | +// | (oldVal, true) | (_, true) | delete | +// ------------------------------------- -------- +func (t *liteTable[V]) Modify(pfx netip.Prefix, cb func(_ V, ok bool) (_ V, del bool)) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + + delta := n.Modify(pfx, cb) + t.sizeUpdate(is4, delta) +} + +// Contains reports whether any stored prefix covers the given IP address. +// Returns false for invalid IP addresses. +// +// This performs longest-prefix matching and returns true if any prefix +// in the routing table contains the IP address, regardless of the associated value. +// +// It does not return the value nor the prefix of the matching item, +// but as a test against an allow-/deny-list it's often sufficient +// and even few nanoseconds faster than [Table.Lookup]. +func (l *liteTable[V]) Contains(ip netip.Addr) bool { + // speed is top priority: no explicit test for ip.IsValid + // if ip is invalid, AsSlice() returns nil, Contains returns false. + is4 := ip.Is4() + n := l.rootNodeByVersion(is4) + + for _, octet := range ip.AsSlice() { + // for contains, any lpm match is good enough, no backtracking needed + if n.Prefixes.Count != 0 && n.Contains(art.OctetToIdx(octet)) { + return true + } + + // stop traversing? + if !n.Children.Test(octet) { + return false + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *nodes.LiteNode[V]: + n = kid // descend down to next trie level + + case *nodes.FringeNode[V]: + // fringe is the default-route for all possible octets below + return true + + case *nodes.LeafNode[V]: + return kid.Prefix.Contains(ip) + } + } + + return false +} + +// Lookup is just a wrapper for Contains. +// Returns the zero value V and true if a prefix matches ip, otherwise zero value and false. +// This method exists to provide a consistent interface for code generation. +func (l *liteTable[V]) Lookup(ip netip.Addr) (val V, exists bool) { + return val, l.Contains(ip) +} + +// LookupPrefix performs a longest prefix match lookup for any address within +// the given prefix. It finds the most specific routing table entry that would +// match any address in the provided prefix range. +// +// This is functionally identical to LookupPrefixLPM but returns only the +// associated value, not the matching prefix itself. +// +// Returns the zero value and true if a matching prefix is found. +// Returns zero value and false if no match exists. +func (l *liteTable[V]) LookupPrefix(pfx netip.Prefix) (val V, exists bool) { + _, exists = l.lookupPrefixLPM(pfx, false) + return +} + +// LookupPrefixLPM performs a longest prefix match lookup for any address within +// the given prefix. It finds the most specific routing table entry that would +// match any address in the provided prefix range. +// +// This is functionally identical to LookupPrefix but additionally returns the +// matching LPM prefix itself along with the value. +// +// This method is slower than LookupPrefix and should only be used if the +// matching lpm entry is also required for other reasons. +// +// Returns the matching prefix, the zero value, and true if found. +// Returns zero values and false if no match exists. +func (l *liteTable[V]) LookupPrefixLPM(pfx netip.Prefix) (lpm netip.Prefix, val V, exists bool) { + lpm, exists = l.lookupPrefixLPM(pfx, true) + return +} + +// lookupPrefixLPM performs a longest prefix match lookup for any address within +// the given prefix. It finds the most specific routing table entry that would +// match any address in the provided prefix range. If withLPM is true, it also +// returns the matching longest prefix. +func (l *liteTable[V]) lookupPrefixLPM(pfx netip.Prefix, withLPM bool) (lpmPfx netip.Prefix, ok bool) { + if !pfx.IsValid() { + return lpmPfx, ok + } + + // canonicalize the prefix + pfx = pfx.Masked() + + ip := pfx.Addr() + pfxLen := pfx.Bits() + is4 := ip.Is4() + octets := ip.AsSlice() + strideCount, modBits := nodes.DivMod8(pfxLen) + + n := l.rootNodeByVersion(is4) + + // record path to leaf node + stack := [nodes.MaxTreeDepth]*nodes.LiteNode[V]{} + + var depth int + var octet byte + +LOOP: + // find the last node on the octets path in the trie, + for depth, octet = range octets { + depth &= nodes.DepthMask // BCE + + // stepped one past the last stride of interest; back up to last and break + if depth > strideCount { + depth-- + break + } + // push current node on stack + stack[depth] = n + + // go down in tight loop to leaf node + if !n.Children.Test(octet) { + break LOOP + } + kid := n.MustGetChild(octet) + + // kid is node or leaf or fringe at octet + switch kid := kid.(type) { + case *nodes.LiteNode[V]: + n = kid + continue LOOP // descend down to next trie level + + case *nodes.LeafNode[V]: + // reached a path compressed prefix, stop traversing + if kid.Prefix.Bits() > pfxLen || !kid.Prefix.Contains(ip) { + break LOOP + } + return kid.Prefix, true + + case *nodes.FringeNode[V]: + // the bits of the fringe are defined by the depth + // maybe the LPM isn't needed, saves some cycles + fringeBits := (depth + 1) << 3 + if fringeBits > pfxLen { + break LOOP + } + + // the LPM isn't needed, saves some cycles + if !withLPM { + return netip.Prefix{}, true + } + + // get the LPM prefix back from ip and depth + // it's a fringe, bits are always /8, /16, /24, ... + fringePfx, _ := ip.Prefix((depth + 1) << 3) + return fringePfx, true + } + } + + // start backtracking, unwind the stack + for ; depth >= 0; depth-- { + depth &= nodes.DepthMask // BCE + + n = stack[depth] + + // longest prefix match, skip if node has no prefixes + if n.PrefixCount() == 0 { + continue + } + + var idx uint8 + octet = octets[depth] + + // only the final stride may have a different prefix len + // all others are just host routes + if depth == strideCount { + idx = art.PfxToIdx(octet, modBits) + } else { + idx = art.OctetToIdx(octet) + } + + // manually inlined: lookupIdx(idx) + var topIdx uint8 + if topIdx, ok = n.Prefixes.IntersectionTop(&lpm.LookupTbl[idx]); ok { + // called from LookupPrefix + if !withLPM { + return netip.Prefix{}, ok + } + + // called from LookupPrefixLPM + + // get the bits from depth and top idx + pfxBits := int(art.PfxBits(depth, topIdx)) + + // calculate the lpmPfx from incoming ip and new mask + // netip.Addr.Prefix canonicalizes. Invariant: art.PfxBits(depth, topIdx) + // yields a valid mask (v4: 0..32, v6: 0..128), so error is impossible. + lpmPfx, _ = ip.Prefix(pfxBits) + return lpmPfx, ok + } + } + + return lpmPfx, ok +} diff --git a/vendor/github.com/gaissmai/bart/litemethodsgenerated.go b/vendor/github.com/gaissmai/bart/litemethodsgenerated.go new file mode 100644 index 0000000..e417f7b --- /dev/null +++ b/vendor/github.com/gaissmai/bart/litemethodsgenerated.go @@ -0,0 +1,731 @@ +// Code generated from file "commonmethods_tmpl.go"; DO NOT EDIT. + +// Copyright (c) 2026 Karl Gaissmaier +// SPDX-License-Identifier: MIT + +package bart + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "iter" + "net/netip" + "slices" + "strings" + + "github.com/gaissmai/bart/internal/nodes" + "github.com/gaissmai/bart/internal/value" +) + +func (t *liteTable[V]) sizeUpdate(is4 bool, delta int) { + if is4 { + t.size4 += delta + return + } + t.size6 += delta +} + +// insert adds or updates a prefix-value pair in the routing table. +// If the prefix already exists, its value is updated; otherwise a new entry is created. +// Invalid prefixes are silently ignored. +// +// The prefix is automatically canonicalized using pfx.Masked() to ensure +// consistent behavior regardless of host bits in the input. +func (t *liteTable[V]) insert(pfx netip.Prefix, val V) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + if exists := n.Insert(pfx, val, 0); exists { + return + } + + // true insert, update size + t.sizeUpdate(is4, 1) +} + +// insertPersist is similar to insert but the receiver isn't modified. +// +// All nodes touched during insert are cloned and a new liteTable is returned. +// This is not a full [liteTable.Clone], all untouched nodes are still referenced +// from both Tables. +// +// If the payload type V contains pointers or needs deep copying, +// implement: +// +// func (v V) Clone() V +// +// The bart package detects this via structural typing and deep‑copies +// values during persistent ops. +// +// Due to cloning overhead this is significantly slower than insert, +// typically taking μsec instead of nsec. +func (t *liteTable[V]) insertPersist(pfx netip.Prefix, val V) *liteTable[V] { + if !pfx.IsValid() { + return t + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + // share size counters; root nodes cloned selectively. + pt := &liteTable[V]{ + size4: t.size4, + size6: t.size6, + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // Clone root node corresponding to the IP version, for copy-on-write. + n := &pt.root4 + + if is4 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + pt.root6 = t.root6 + } else { + pt.root4 = t.root4 + pt.root6 = *t.root6.CloneFlat(cloneFn) + + n = &pt.root6 + } + + if !n.InsertPersist(cloneFn, pfx, val, 0) { + pt.sizeUpdate(is4, 1) + } + + return pt +} + +// Delete removes the exact prefix pfx from the table in-place. +// +// This is an exact-match operation (no LPM). If pfx exists, the entry is +// removed. If pfx does not exist or pfx is invalid, the table is left unchanged. +// +// The prefix is canonicalized (Masked) before lookup. +func (t *liteTable[V]) Delete(pfx netip.Prefix) { + if !pfx.IsValid() { + return + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + if exists := n.Delete(pfx); exists { + t.sizeUpdate(is4, -1) + } +} + +// Get performs an exact-prefix lookup and returns whether the exact +// prefix exists. The prefix is canonicalized (Masked) before lookup. +// +// This is an exact-match operation (no LPM). The prefix must match exactly +// in both address and prefix length to be found. If pfx exists, the +// associated value (zero value for Lite) and found=true is returned. +// If pfx does not exist or pfx is invalid, the zero value for V and +// exists=false is returned. +// +// For longest-prefix-match (LPM) lookups, use Contains(ip), Lookup(ip), +// LookupPrefix(pfx) or LookupPrefixLPM(pfx) instead. +func (t *liteTable[V]) Get(pfx netip.Prefix) (val V, exists bool) { + if !pfx.IsValid() { + return val, exists + } + // canonicalize prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + return n.Get(pfx) +} + +// DeletePersist is similar to Delete but does not modify the receiver. +// +// It performs a copy-on-write delete operation, cloning all nodes touched during +// deletion and returning a new liteTable reflecting the change. +// +// If the prefix is invalid or doesn't exist, the original table is +// returned unchanged. +// +// If the payload type V contains pointers or requires deep copying, +// it must implement the Clone method for correct cloning. +// +// Due to cloning overhead this is significantly slower than Delete, +// typically taking μsec instead of nsec. +func (t *liteTable[V]) DeletePersist(pfx netip.Prefix) *liteTable[V] { + if !pfx.IsValid() { + return t + } + + // canonicalize prefix + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + // Preflight check: avoid cloning if prefix doesn't exist + n := t.rootNodeByVersion(is4) + if _, found := n.Get(pfx); !found { + return t + } + + // share size counters; root nodes cloned selectively. + pt := &liteTable[V]{ + size4: t.size4, + size6: t.size6, + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // Clone root node corresponding to the IP version, for copy-on-write. + if is4 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + pt.root6 = t.root6 + n = &pt.root4 + } else { + pt.root4 = t.root4 + pt.root6 = *t.root6.CloneFlat(cloneFn) + n = &pt.root6 + } + + if exists := n.DeletePersist(cloneFn, pfx); exists { + pt.sizeUpdate(is4, -1) + } + + return pt +} + +// ModifyPersist is similar to Modify but the receiver isn't modified and +// a new *liteTable is returned. +func (t *liteTable[V]) ModifyPersist(pfx netip.Prefix, cb func(_ V, ok bool) (_ V, del bool)) *liteTable[V] { + if !pfx.IsValid() { + return t + } + + // make a cheap test in front of expensive operation + oldVal, ok := t.Get(pfx) + val := oldVal + + // to clone or not to clone ... + cloneFn := value.CloneFnFactory[V]() + if cloneFn != nil && ok { + val = cloneFn(oldVal) + } + + newVal, del := cb(val, ok) + + switch { + case !ok && del: // no-op + return t + + case !ok && !del: // insert + return t.InsertPersist(pfx, newVal) + + case ok && !del: // update + return t.InsertPersist(pfx, newVal) + + case ok && del: // delete + return t.DeletePersist(pfx) + } + + panic("unreachable") +} + +// Supernets returns an iterator over all supernet routes that cover the given prefix pfx. +// +// The traversal searches both exact-length and shorter (less specific) prefixes that +// include pfx. Starting from the most specific position in the trie, +// it walks upward through parent nodes and yields any matching entries found at each level. +// +// The iteration order is reverse-CIDR: from longest prefix match (LPM) towards +// least-specific routes. +// +// This can be used to enumerate all covering supernet routes in routing-based +// policy engines, diagnostics tools, or fallback resolution logic. +// +// Example: +// +// for supernet, val := range table.Supernets(netip.MustParsePrefix("192.0.2.128/25")) { +// fmt.Println("Covered by:", supernet, "->", val) +// } +// +// The iteration can be stopped early by breaking from the range loop. +// Returns an empty iterator if the prefix is invalid. +func (t *liteTable[V]) Supernets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if !pfx.IsValid() { + return + } + + // canonicalize the prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + n.Supernets(pfx, yield) + } +} + +// Subnets returns an iterator over all subnets of the given prefix +// in natural CIDR sort order. This includes prefixes of the same length +// (exact match) and longer (more specific) prefixes that are contained +// within the given prefix. +// +// Example: +// +// for sub, val := range table.Subnets(netip.MustParsePrefix("10.0.0.0/8")) { +// fmt.Println("Covered:", sub, "->", val) +// } +// +// The iteration can be stopped early by breaking from the range loop. +// Returns an empty iterator if the prefix is invalid. +func (t *liteTable[V]) Subnets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + if !pfx.IsValid() { + return + } + + pfx = pfx.Masked() + is4 := pfx.Addr().Is4() + + n := t.rootNodeByVersion(is4) + n.Subnets(pfx, yield) + } +} + +// OverlapsPrefix reports whether any prefix in the routing table overlaps with +// the given prefix. Two prefixes overlap if they share any IP addresses. +// +// The check is bidirectional: it returns true if the input prefix is covered by an existing +// route, or if any stored route is itself contained within the input prefix. +// +// Internally, the function normalizes the prefix and descends the relevant trie branch, +// using stride-based logic to identify overlap without performing a full lookup. +// +// This is useful for containment tests, route validation, or policy checks using prefix +// semantics without retrieving exact matches. +func (t *liteTable[V]) OverlapsPrefix(pfx netip.Prefix) bool { + if !pfx.IsValid() { + return false + } + + // canonicalize the prefix + pfx = pfx.Masked() + + is4 := pfx.Addr().Is4() + n := t.rootNodeByVersion(is4) + + return n.OverlapsPrefixAtDepth(pfx, 0) +} + +// Overlaps reports whether any route in the receiver table overlaps +// with a route in the other table, in either direction. +// +// The overlap check is bidirectional: it returns true if any IP prefix +// in the receiver is covered by the other table, or vice versa. +// This includes partial overlaps, exact matches, and supernet/subnet relationships. +// +// Both IPv4 and IPv6 route trees are compared independently. If either +// tree has overlapping routes, the function returns true. +// +// This is useful for conflict detection, policy enforcement, +// or validating mutually exclusive routing domains. +func (t *liteTable[V]) Overlaps(o *liteTable[V]) bool { + return t.Overlaps4(o) || t.Overlaps6(o) +} + +// Overlaps4 is like [liteTable.Overlaps] but for the v4 routing table only. +func (t *liteTable[V]) Overlaps4(o *liteTable[V]) bool { + if t.size4 == 0 || o.size4 == 0 { + return false + } + return t.root4.Overlaps(&o.root4, 0) +} + +// Overlaps6 is like [liteTable.Overlaps] but for the v6 routing table only. +func (t *liteTable[V]) Overlaps6(o *liteTable[V]) bool { + if t.size6 == 0 || o.size6 == 0 { + return false + } + return t.root6.Overlaps(&o.root6, 0) +} + +// Union merges another routing table into the receiver table, modifying it in-place. +// +// All prefixes and values from the other table (o) are inserted into the receiver. +// If a duplicate prefix exists in both tables, the value from o replaces the existing entry. +// This duplicate is shallow-copied by default, but if the value type V implements the +// Clone method, the value is deeply cloned before insertion. See also liteTable.Clone. +func (t *liteTable[V]) Union(o *liteTable[V]) { + // panics on nil receiver + _ = t.size4 + + // panics on nil argument + if o.size4 == 0 && o.size6 == 0 { + return + } + // t is unchanged + if o == t { + return + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + dup4 := t.root4.UnionRec(cloneFn, &o.root4, 0) + dup6 := t.root6.UnionRec(cloneFn, &o.root6, 0) + + t.size4 += o.size4 - dup4 + t.size6 += o.size6 - dup6 +} + +// UnionPersist is similar to [Union] but the receiver isn't modified. +// +// All nodes touched during union are cloned and a new *liteTable is returned. +// If o is empty, no nodes are touched and the receiver may be +// returned unchanged. +func (t *liteTable[V]) UnionPersist(o *liteTable[V]) *liteTable[V] { + // panics on nil receiver + _ = t.size4 + + // panics on nil argument + if o.size4 == 0 && o.size6 == 0 { + return t + } + if o == t { + return t + } + + // Create a cloning function for deep copying values; + // returns nil if V does not provide a Clone() V method. + cloneFn := value.CloneFnFactory[V]() + + // new liteTable with root nodes just copied. + pt := &liteTable[V]{ + root4: t.root4, + root6: t.root6, + // + size4: t.size4, + size6: t.size6, + } + + // only clone the root node if there is something to union + if o.size4 != 0 { + pt.root4 = *t.root4.CloneFlat(cloneFn) + } + if o.size6 != 0 { + pt.root6 = *t.root6.CloneFlat(cloneFn) + } + + dup4 := pt.root4.UnionRecPersist(cloneFn, &o.root4, 0) + dup6 := pt.root6.UnionRecPersist(cloneFn, &o.root6, 0) + + pt.size4 += o.size4 - dup4 + pt.size6 += o.size6 - dup6 + + return pt +} + +// Equal checks whether two tables are structurally and semantically equal. +// It ensures both trees (IPv4-based and IPv6-based) have the same sizes and +// recursively compares their root nodes. +// +// If V implements an `Equal(V) bool` method, its custom equality logic is used. +// Otherwise, values are compared directly using the == operator. +// +// Note: If V implements `Equal(V) bool` with a pointer receiver, the Equal +// method should handle nil receivers gracefully. +// +// ATTENTION: If V is not comparable at runtime (such as a slice or map without an `Equal` +// method), a runtime panic will occur. +func (t *liteTable[V]) Equal(o *liteTable[V]) bool { + if t.size4 != o.size4 || t.size6 != o.size6 { + return false + } + if o == t { + return true + } + + return t.root4.EqualRec(&o.root4) && t.root6.EqualRec(&o.root6) +} + +// Clone returns a copy of the routing table. +// The payload of type V is shallow copied by default. To enable deep copying, +// implement the following method on your value type: +// +// Clone() V +// +// Example: +// +// type MyValue struct { Data []byte } +// func (v MyValue) Clone() MyValue { +// return MyValue{Data: slices.Clone(v.Data)} +// } +// +// The bart package will automatically detect and use this method via Go's +// structural typing. +// +// Note: If V implements Clone() V with a pointer receiver, the Clone +// method should handle nil receivers gracefully. +func (t *liteTable[V]) Clone() *liteTable[V] { + c := new(liteTable[V]) + + cloneFn := value.CloneFnFactory[V]() + + c.root4 = *t.root4.CloneRec(cloneFn) + c.root6 = *t.root6.CloneRec(cloneFn) + + c.size4 = t.size4 + c.size6 = t.size6 + + return c +} + +// Size returns the prefix count. +func (t *liteTable[V]) Size() int { + return t.size4 + t.size6 +} + +// Size4 returns the IPv4 prefix count. +func (t *liteTable[V]) Size4() int { + return t.size4 +} + +// Size6 returns the IPv6 prefix count. +func (t *liteTable[V]) Size6() int { + return t.size6 +} + +// All returns an iterator over all prefix–value pairs in the table. +// +// The iteration order is unspecified and may vary between calls; for a stable order, +// use [liteTable.AllSorted]. +// +// IMPORTANT: Modifying the table during iteration is not allowed, +// as this would interfere with the internal traversal and may corrupt or +// prematurely terminate the iteration. +func (t *liteTable[V]) All() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRec(stridePath{}, 0, true, yield) && t.root6.AllRec(stridePath{}, 0, false, yield) + } +} + +// All4 is like [liteTable.All] but only for the v4 routing table. +func (t *liteTable[V]) All4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRec(stridePath{}, 0, true, yield) + } +} + +// All6 is like [liteTable.All] but only for the v6 routing table. +func (t *liteTable[V]) All6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root6.AllRec(stridePath{}, 0, false, yield) + } +} + +// AllSorted is like [liteTable.All] but the iteration is ordered in canonical +// CIDR prefix sort order. +func (t *liteTable[V]) AllSorted() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRecSorted(stridePath{}, 0, true, yield) && + t.root6.AllRecSorted(stridePath{}, 0, false, yield) + } +} + +// AllSorted4 is like [liteTable.AllSorted] but only for the v4 routing table. +func (t *liteTable[V]) AllSorted4() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root4.AllRecSorted(stridePath{}, 0, true, yield) + } +} + +// AllSorted6 is like [liteTable.AllSorted] but only for the v6 routing table. +func (t *liteTable[V]) AllSorted6() iter.Seq2[netip.Prefix, V] { + return func(yield func(netip.Prefix, V) bool) { + _ = t.root6.AllRecSorted(stridePath{}, 0, false, yield) + } +} + +// Fprint writes a hierarchical tree diagram of the ordered CIDRs +// with default formatted payload V to w. +// +// The order from top to bottom is in ascending order of the prefix address +// and the subtree structure is determined by the CIDRs coverage. +// +// ▼ +// ├─ 10.0.0.0/8 (V) +// │ ├─ 10.0.0.0/24 (V) +// │ └─ 10.0.1.0/24 (V) +// ├─ 127.0.0.0/8 (V) +// │ └─ 127.0.0.1/32 (V) +// ├─ 169.254.0.0/16 (V) +// ├─ 172.16.0.0/12 (V) +// └─ 192.168.0.0/16 (V) +// └─ 192.168.1.0/24 (V) +// ▼ +// └─ ::/0 (V) +// ├─ ::1/128 (V) +// ├─ 2000::/3 (V) +// │ └─ 2001:db8::/32 (V) +// └─ fe80::/10 (V) +func (t *liteTable[V]) Fprint(w io.Writer) error { + if w == nil && t != nil { + return fmt.Errorf("nil writer") + } + + // v4 + if err := t.fprint(w, true); err != nil { + return err + } + + // v6 + if err := t.fprint(w, false); err != nil { + return err + } + + return nil +} + +// fprint is the version dependent adapter to fprintRec. +func (t *liteTable[V]) fprint(w io.Writer, is4 bool) error { + n := t.rootNodeByVersion(is4) + if n.IsEmpty() { + return nil + } + + if _, err := fmt.Fprint(w, "▼\n"); err != nil { + return err + } + + startParent := nodes.TrieItem[V]{ + Node: nil, + Idx: 0, + Path: stridePath{}, + Is4: is4, + } + + return n.FprintRec(w, startParent, "") +} + +// MarshalText implements the [encoding.TextMarshaler] interface, +// just a wrapper for [liteTable.Fprint]. +func (t *liteTable[V]) MarshalText() ([]byte, error) { + w := new(bytes.Buffer) + if err := t.Fprint(w); err != nil { + return nil, err + } + + return w.Bytes(), nil +} + +// MarshalJSON dumps the table into two sorted lists: for ipv4 and ipv6. +// Every root and subnet is an array, not a map, because the order matters. +func (t *liteTable[V]) MarshalJSON() ([]byte, error) { + result := struct { + Ipv4 []DumpListNode[V] `json:"ipv4,omitempty"` + Ipv6 []DumpListNode[V] `json:"ipv6,omitempty"` + }{ + Ipv4: t.DumpList4(), + Ipv6: t.DumpList6(), + } + + buf, err := json.Marshal(result) + if err != nil { + return nil, err + } + + return buf, nil +} + +// DumpList4 dumps the ipv4 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build the text or JSON serialization. +func (t *liteTable[V]) DumpList4() []DumpListNode[V] { + return t.dumpListRec(&t.root4, 0, stridePath{}, 0, true) +} + +// DumpList6 dumps the ipv6 tree into a list of roots and their subnets. +// It can be used to analyze the tree or build custom JSON representation. +func (t *liteTable[V]) DumpList6() []DumpListNode[V] { + return t.dumpListRec(&t.root6, 0, stridePath{}, 0, false) +} + +// dumpListRec, build the data structure rec-descent with the help of directItemsRec. +// anyNode is nodes.BartNode, nodes.FastNode or nodes.LiteNode +func (t *liteTable[V]) dumpListRec(anyNode any, parentIdx uint8, path stridePath, depth int, is4 bool) []DumpListNode[V] { + // recursion stop condition + if anyNode == nil { + return nil + } + + // the same method is generated for all table types, therefore + // type assert to the smallest needed interface. + // The panic on wrong type assertion is by intention, MUST NOT happen + n := anyNode.(interface { + DirectItemsRec(uint8, stridePath, int, bool) []nodes.TrieItem[V] + }) + + directItems := n.DirectItemsRec(parentIdx, path, depth, is4) + + // sort the items by prefix + slices.SortFunc(directItems, func(a, b nodes.TrieItem[V]) int { + return nodes.CmpPrefix(a.Cidr, b.Cidr) + }) + + dumpNodes := make([]DumpListNode[V], 0, len(directItems)) + + for _, item := range directItems { + dumpNodes = append(dumpNodes, DumpListNode[V]{ + CIDR: item.Cidr, + Value: item.Val, + // build it rec-descent, item.Node is also from type any + Subnets: t.dumpListRec(item.Node, item.Idx, item.Path, item.Depth, is4), + }) + } + + return dumpNodes +} + +// dumpString is just a wrapper for dump. +func (t *liteTable[V]) dumpString() string { + w := new(strings.Builder) + t.dump(w) + + return w.String() +} + +// dump the table structure and all the nodes to w. +func (t *liteTable[V]) dump(w io.Writer) { + if t.size4 > 0 { + stats := t.root4.StatsRec() + fmt.Fprintln(w) + fmt.Fprintf(w, "### IPv4: size(%d), subnodes(%d), prefixes(%d), leaves(%d), fringes(%d)", + t.size4, stats.SubNodes, stats.Prefixes, stats.Leaves, stats.Fringes) + + t.root4.DumpRec(w, stridePath{}, 0, true) + } + + if t.size6 > 0 { + stats := t.root6.StatsRec() + fmt.Fprintln(w) + fmt.Fprintf(w, "### IPv6: size(%d), subnodes(%d), prefixes(%d), leaves(%d), fringes(%d)", + t.size6, stats.SubNodes, stats.Prefixes, stats.Leaves, stats.Fringes) + + t.root6.DumpRec(w, stridePath{}, 0, false) + } +} diff --git a/vendor/github.com/gaissmai/bart/lpm_lookuptbl.go b/vendor/github.com/gaissmai/bart/lpm_lookuptbl.go deleted file mode 100644 index 751a8d5..0000000 --- a/vendor/github.com/gaissmai/bart/lpm_lookuptbl.go +++ /dev/null @@ -1,538 +0,0 @@ -package bart - -import "github.com/gaissmai/bart/internal/bitset" - -// lpmLookupTbl is the backtracking sequence in the complete binary tree as bitstring. -// -// for idx := 1; idx > 0; idx >>= 1 { b.Set(idx) } -// -// allows a one shot bitset intersection algorithm: -// -// func (n *node[V]) lpmTest(idx uint) bool { -// return n.prefixes.IntersectsAny(lpmLookupTbl[idx]) -// } -// -// instead of a sequence of single bitset tests: -// -// func (n *node[V]) lpmTest(idx uint) bool { -// for ; idx > 0; idx >>= 1 { -// if n.prefixes.Test(idx) { -// return true -// } -// } -// return false -// } -var lpmLookupTbl = [512]bitset.BitSet{ - /* idx: 0 */ {}, // invalid - /* idx: 1 */ {0x2}, // 0b0000_0010 - /* idx: 2 */ {0x6}, // 0b0000_0110 - /* idx: 3 */ {0xa}, // 0b0000_1010 - /* idx: 4 */ {0x16}, // ... - /* idx: 5 */ {0x26}, - /* idx: 6 */ {0x4a}, - /* idx: 7 */ {0x8a}, - /* idx: 8 */ {0x116}, - /* idx: 9 */ {0x216}, - /* idx: 10 */ {0x426}, - /* idx: 11 */ {0x826}, - /* idx: 12 */ {0x104a}, - /* idx: 13 */ {0x204a}, - /* idx: 14 */ {0x408a}, - /* idx: 15 */ {0x808a}, - /* idx: 16 */ {0x10116}, - /* idx: 17 */ {0x20116}, - /* idx: 18 */ {0x40216}, - /* idx: 19 */ {0x80216}, - /* idx: 20 */ {0x100426}, - /* idx: 21 */ {0x200426}, - /* idx: 22 */ {0x400826}, - /* idx: 23 */ {0x800826}, - /* idx: 24 */ {0x100104a}, - /* idx: 25 */ {0x200104a}, - /* idx: 26 */ {0x400204a}, - /* idx: 27 */ {0x800204a}, - /* idx: 28 */ {0x1000408a}, - /* idx: 29 */ {0x2000408a}, - /* idx: 30 */ {0x4000808a}, - /* idx: 31 */ {0x8000808a}, - /* idx: 32 */ {0x100010116}, - /* idx: 33 */ {0x200010116}, - /* idx: 34 */ {0x400020116}, - /* idx: 35 */ {0x800020116}, - /* idx: 36 */ {0x1000040216}, - /* idx: 37 */ {0x2000040216}, - /* idx: 38 */ {0x4000080216}, - /* idx: 39 */ {0x8000080216}, - /* idx: 40 */ {0x10000100426}, - /* idx: 41 */ {0x20000100426}, - /* idx: 42 */ {0x40000200426}, - /* idx: 43 */ {0x80000200426}, - /* idx: 44 */ {0x100000400826}, - /* idx: 45 */ {0x200000400826}, - /* idx: 46 */ {0x400000800826}, - /* idx: 47 */ {0x800000800826}, - /* idx: 48 */ {0x100000100104a}, - /* idx: 49 */ {0x200000100104a}, - /* idx: 50 */ {0x400000200104a}, - /* idx: 51 */ {0x800000200104a}, - /* idx: 52 */ {0x1000000400204a}, - /* idx: 53 */ {0x2000000400204a}, - /* idx: 54 */ {0x4000000800204a}, - /* idx: 55 */ {0x8000000800204a}, - /* idx: 56 */ {0x10000001000408a}, - /* idx: 57 */ {0x20000001000408a}, - /* idx: 58 */ {0x40000002000408a}, - /* idx: 59 */ {0x80000002000408a}, - /* idx: 60 */ {0x100000004000808a}, - /* idx: 61 */ {0x200000004000808a}, - /* idx: 62 */ {0x400000008000808a}, - /* idx: 63 */ {0x800000008000808a}, - /* idx: 64 */ {0x100010116, 0x1}, - /* idx: 65 */ {0x100010116, 0x2}, - /* idx: 66 */ {0x200010116, 0x4}, - /* idx: 67 */ {0x200010116, 0x8}, - /* idx: 68 */ {0x400020116, 0x10}, - /* idx: 69 */ {0x400020116, 0x20}, - /* idx: 70 */ {0x800020116, 0x40}, - /* idx: 71 */ {0x800020116, 0x80}, - /* idx: 72 */ {0x1000040216, 0x100}, - /* idx: 73 */ {0x1000040216, 0x200}, - /* idx: 74 */ {0x2000040216, 0x400}, - /* idx: 75 */ {0x2000040216, 0x800}, - /* idx: 76 */ {0x4000080216, 0x1000}, - /* idx: 77 */ {0x4000080216, 0x2000}, - /* idx: 78 */ {0x8000080216, 0x4000}, - /* idx: 79 */ {0x8000080216, 0x8000}, - /* idx: 80 */ {0x10000100426, 0x10000}, - /* idx: 81 */ {0x10000100426, 0x20000}, - /* idx: 82 */ {0x20000100426, 0x40000}, - /* idx: 83 */ {0x20000100426, 0x80000}, - /* idx: 84 */ {0x40000200426, 0x100000}, - /* idx: 85 */ {0x40000200426, 0x200000}, - /* idx: 86 */ {0x80000200426, 0x400000}, - /* idx: 87 */ {0x80000200426, 0x800000}, - /* idx: 88 */ {0x100000400826, 0x1000000}, - /* idx: 89 */ {0x100000400826, 0x2000000}, - /* idx: 90 */ {0x200000400826, 0x4000000}, - /* idx: 91 */ {0x200000400826, 0x8000000}, - /* idx: 92 */ {0x400000800826, 0x10000000}, - /* idx: 93 */ {0x400000800826, 0x20000000}, - /* idx: 94 */ {0x800000800826, 0x40000000}, - /* idx: 95 */ {0x800000800826, 0x80000000}, - /* idx: 96 */ {0x100000100104a, 0x100000000}, - /* idx: 97 */ {0x100000100104a, 0x200000000}, - /* idx: 98 */ {0x200000100104a, 0x400000000}, - /* idx: 99 */ {0x200000100104a, 0x800000000}, - /* idx: 100 */ {0x400000200104a, 0x1000000000}, - /* idx: 101 */ {0x400000200104a, 0x2000000000}, - /* idx: 102 */ {0x800000200104a, 0x4000000000}, - /* idx: 103 */ {0x800000200104a, 0x8000000000}, - /* idx: 104 */ {0x1000000400204a, 0x10000000000}, - /* idx: 105 */ {0x1000000400204a, 0x20000000000}, - /* idx: 106 */ {0x2000000400204a, 0x40000000000}, - /* idx: 107 */ {0x2000000400204a, 0x80000000000}, - /* idx: 108 */ {0x4000000800204a, 0x100000000000}, - /* idx: 109 */ {0x4000000800204a, 0x200000000000}, - /* idx: 110 */ {0x8000000800204a, 0x400000000000}, - /* idx: 111 */ {0x8000000800204a, 0x800000000000}, - /* idx: 112 */ {0x10000001000408a, 0x1000000000000}, - /* idx: 113 */ {0x10000001000408a, 0x2000000000000}, - /* idx: 114 */ {0x20000001000408a, 0x4000000000000}, - /* idx: 115 */ {0x20000001000408a, 0x8000000000000}, - /* idx: 116 */ {0x40000002000408a, 0x10000000000000}, - /* idx: 117 */ {0x40000002000408a, 0x20000000000000}, - /* idx: 118 */ {0x80000002000408a, 0x40000000000000}, - /* idx: 119 */ {0x80000002000408a, 0x80000000000000}, - /* idx: 120 */ {0x100000004000808a, 0x100000000000000}, - /* idx: 121 */ {0x100000004000808a, 0x200000000000000}, - /* idx: 122 */ {0x200000004000808a, 0x400000000000000}, - /* idx: 123 */ {0x200000004000808a, 0x800000000000000}, - /* idx: 124 */ {0x400000008000808a, 0x1000000000000000}, - /* idx: 125 */ {0x400000008000808a, 0x2000000000000000}, - /* idx: 126 */ {0x800000008000808a, 0x4000000000000000}, - /* idx: 127 */ {0x800000008000808a, 0x8000000000000000}, - /* idx: 128 */ {0x100010116, 0x1, 0x1}, - /* idx: 129 */ {0x100010116, 0x1, 0x2}, - /* idx: 130 */ {0x100010116, 0x2, 0x4}, - /* idx: 131 */ {0x100010116, 0x2, 0x8}, - /* idx: 132 */ {0x200010116, 0x4, 0x10}, - /* idx: 133 */ {0x200010116, 0x4, 0x20}, - /* idx: 134 */ {0x200010116, 0x8, 0x40}, - /* idx: 135 */ {0x200010116, 0x8, 0x80}, - /* idx: 136 */ {0x400020116, 0x10, 0x100}, - /* idx: 137 */ {0x400020116, 0x10, 0x200}, - /* idx: 138 */ {0x400020116, 0x20, 0x400}, - /* idx: 139 */ {0x400020116, 0x20, 0x800}, - /* idx: 140 */ {0x800020116, 0x40, 0x1000}, - /* idx: 141 */ {0x800020116, 0x40, 0x2000}, - /* idx: 142 */ {0x800020116, 0x80, 0x4000}, - /* idx: 143 */ {0x800020116, 0x80, 0x8000}, - /* idx: 144 */ {0x1000040216, 0x100, 0x10000}, - /* idx: 145 */ {0x1000040216, 0x100, 0x20000}, - /* idx: 146 */ {0x1000040216, 0x200, 0x40000}, - /* idx: 147 */ {0x1000040216, 0x200, 0x80000}, - /* idx: 148 */ {0x2000040216, 0x400, 0x100000}, - /* idx: 149 */ {0x2000040216, 0x400, 0x200000}, - /* idx: 150 */ {0x2000040216, 0x800, 0x400000}, - /* idx: 151 */ {0x2000040216, 0x800, 0x800000}, - /* idx: 152 */ {0x4000080216, 0x1000, 0x1000000}, - /* idx: 153 */ {0x4000080216, 0x1000, 0x2000000}, - /* idx: 154 */ {0x4000080216, 0x2000, 0x4000000}, - /* idx: 155 */ {0x4000080216, 0x2000, 0x8000000}, - /* idx: 156 */ {0x8000080216, 0x4000, 0x10000000}, - /* idx: 157 */ {0x8000080216, 0x4000, 0x20000000}, - /* idx: 158 */ {0x8000080216, 0x8000, 0x40000000}, - /* idx: 159 */ {0x8000080216, 0x8000, 0x80000000}, - /* idx: 160 */ {0x10000100426, 0x10000, 0x100000000}, - /* idx: 161 */ {0x10000100426, 0x10000, 0x200000000}, - /* idx: 162 */ {0x10000100426, 0x20000, 0x400000000}, - /* idx: 163 */ {0x10000100426, 0x20000, 0x800000000}, - /* idx: 164 */ {0x20000100426, 0x40000, 0x1000000000}, - /* idx: 165 */ {0x20000100426, 0x40000, 0x2000000000}, - /* idx: 166 */ {0x20000100426, 0x80000, 0x4000000000}, - /* idx: 167 */ {0x20000100426, 0x80000, 0x8000000000}, - /* idx: 168 */ {0x40000200426, 0x100000, 0x10000000000}, - /* idx: 169 */ {0x40000200426, 0x100000, 0x20000000000}, - /* idx: 170 */ {0x40000200426, 0x200000, 0x40000000000}, - /* idx: 171 */ {0x40000200426, 0x200000, 0x80000000000}, - /* idx: 172 */ {0x80000200426, 0x400000, 0x100000000000}, - /* idx: 173 */ {0x80000200426, 0x400000, 0x200000000000}, - /* idx: 174 */ {0x80000200426, 0x800000, 0x400000000000}, - /* idx: 175 */ {0x80000200426, 0x800000, 0x800000000000}, - /* idx: 176 */ {0x100000400826, 0x1000000, 0x1000000000000}, - /* idx: 177 */ {0x100000400826, 0x1000000, 0x2000000000000}, - /* idx: 178 */ {0x100000400826, 0x2000000, 0x4000000000000}, - /* idx: 179 */ {0x100000400826, 0x2000000, 0x8000000000000}, - /* idx: 180 */ {0x200000400826, 0x4000000, 0x10000000000000}, - /* idx: 181 */ {0x200000400826, 0x4000000, 0x20000000000000}, - /* idx: 182 */ {0x200000400826, 0x8000000, 0x40000000000000}, - /* idx: 183 */ {0x200000400826, 0x8000000, 0x80000000000000}, - /* idx: 184 */ {0x400000800826, 0x10000000, 0x100000000000000}, - /* idx: 185 */ {0x400000800826, 0x10000000, 0x200000000000000}, - /* idx: 186 */ {0x400000800826, 0x20000000, 0x400000000000000}, - /* idx: 187 */ {0x400000800826, 0x20000000, 0x800000000000000}, - /* idx: 188 */ {0x800000800826, 0x40000000, 0x1000000000000000}, - /* idx: 189 */ {0x800000800826, 0x40000000, 0x2000000000000000}, - /* idx: 190 */ {0x800000800826, 0x80000000, 0x4000000000000000}, - /* idx: 191 */ {0x800000800826, 0x80000000, 0x8000000000000000}, - /* idx: 192 */ {0x100000100104a, 0x100000000, 0x0, 0x1}, - /* idx: 193 */ {0x100000100104a, 0x100000000, 0x0, 0x2}, - /* idx: 194 */ {0x100000100104a, 0x200000000, 0x0, 0x4}, - /* idx: 195 */ {0x100000100104a, 0x200000000, 0x0, 0x8}, - /* idx: 196 */ {0x200000100104a, 0x400000000, 0x0, 0x10}, - /* idx: 197 */ {0x200000100104a, 0x400000000, 0x0, 0x20}, - /* idx: 198 */ {0x200000100104a, 0x800000000, 0x0, 0x40}, - /* idx: 199 */ {0x200000100104a, 0x800000000, 0x0, 0x80}, - /* idx: 200 */ {0x400000200104a, 0x1000000000, 0x0, 0x100}, - /* idx: 201 */ {0x400000200104a, 0x1000000000, 0x0, 0x200}, - /* idx: 202 */ {0x400000200104a, 0x2000000000, 0x0, 0x400}, - /* idx: 203 */ {0x400000200104a, 0x2000000000, 0x0, 0x800}, - /* idx: 204 */ {0x800000200104a, 0x4000000000, 0x0, 0x1000}, - /* idx: 205 */ {0x800000200104a, 0x4000000000, 0x0, 0x2000}, - /* idx: 206 */ {0x800000200104a, 0x8000000000, 0x0, 0x4000}, - /* idx: 207 */ {0x800000200104a, 0x8000000000, 0x0, 0x8000}, - /* idx: 208 */ {0x1000000400204a, 0x10000000000, 0x0, 0x10000}, - /* idx: 209 */ {0x1000000400204a, 0x10000000000, 0x0, 0x20000}, - /* idx: 210 */ {0x1000000400204a, 0x20000000000, 0x0, 0x40000}, - /* idx: 211 */ {0x1000000400204a, 0x20000000000, 0x0, 0x80000}, - /* idx: 212 */ {0x2000000400204a, 0x40000000000, 0x0, 0x100000}, - /* idx: 213 */ {0x2000000400204a, 0x40000000000, 0x0, 0x200000}, - /* idx: 214 */ {0x2000000400204a, 0x80000000000, 0x0, 0x400000}, - /* idx: 215 */ {0x2000000400204a, 0x80000000000, 0x0, 0x800000}, - /* idx: 216 */ {0x4000000800204a, 0x100000000000, 0x0, 0x1000000}, - /* idx: 217 */ {0x4000000800204a, 0x100000000000, 0x0, 0x2000000}, - /* idx: 218 */ {0x4000000800204a, 0x200000000000, 0x0, 0x4000000}, - /* idx: 219 */ {0x4000000800204a, 0x200000000000, 0x0, 0x8000000}, - /* idx: 220 */ {0x8000000800204a, 0x400000000000, 0x0, 0x10000000}, - /* idx: 221 */ {0x8000000800204a, 0x400000000000, 0x0, 0x20000000}, - /* idx: 222 */ {0x8000000800204a, 0x800000000000, 0x0, 0x40000000}, - /* idx: 223 */ {0x8000000800204a, 0x800000000000, 0x0, 0x80000000}, - /* idx: 224 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x100000000}, - /* idx: 225 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x200000000}, - /* idx: 226 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x400000000}, - /* idx: 227 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x800000000}, - /* idx: 228 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x1000000000}, - /* idx: 229 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x2000000000}, - /* idx: 230 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x4000000000}, - /* idx: 231 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x8000000000}, - /* idx: 232 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x10000000000}, - /* idx: 233 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x20000000000}, - /* idx: 234 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x40000000000}, - /* idx: 235 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x80000000000}, - /* idx: 236 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x100000000000}, - /* idx: 237 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x200000000000}, - /* idx: 238 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x400000000000}, - /* idx: 239 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x800000000000}, - /* idx: 240 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x1000000000000}, - /* idx: 241 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x2000000000000}, - /* idx: 242 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x4000000000000}, - /* idx: 243 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x8000000000000}, - /* idx: 244 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x10000000000000}, - /* idx: 245 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x20000000000000}, - /* idx: 246 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x40000000000000}, - /* idx: 247 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x80000000000000}, - /* idx: 248 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x100000000000000}, - /* idx: 249 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x200000000000000}, - /* idx: 250 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x400000000000000}, - /* idx: 251 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x800000000000000}, - /* idx: 252 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x1000000000000000}, - /* idx: 253 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x2000000000000000}, - /* idx: 254 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x4000000000000000}, - /* idx: 255 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x8000000000000000}, - /* idx: 256 */ {0x100010116, 0x1, 0x1, 0x0, 0x1}, - /* idx: 257 */ {0x100010116, 0x1, 0x1, 0x0, 0x2}, - /* idx: 258 */ {0x100010116, 0x1, 0x2, 0x0, 0x4}, - /* idx: 259 */ {0x100010116, 0x1, 0x2, 0x0, 0x8}, - /* idx: 260 */ {0x100010116, 0x2, 0x4, 0x0, 0x10}, - /* idx: 261 */ {0x100010116, 0x2, 0x4, 0x0, 0x20}, - /* idx: 262 */ {0x100010116, 0x2, 0x8, 0x0, 0x40}, - /* idx: 263 */ {0x100010116, 0x2, 0x8, 0x0, 0x80}, - /* idx: 264 */ {0x200010116, 0x4, 0x10, 0x0, 0x100}, - /* idx: 265 */ {0x200010116, 0x4, 0x10, 0x0, 0x200}, - /* idx: 266 */ {0x200010116, 0x4, 0x20, 0x0, 0x400}, - /* idx: 267 */ {0x200010116, 0x4, 0x20, 0x0, 0x800}, - /* idx: 268 */ {0x200010116, 0x8, 0x40, 0x0, 0x1000}, - /* idx: 269 */ {0x200010116, 0x8, 0x40, 0x0, 0x2000}, - /* idx: 270 */ {0x200010116, 0x8, 0x80, 0x0, 0x4000}, - /* idx: 271 */ {0x200010116, 0x8, 0x80, 0x0, 0x8000}, - /* idx: 272 */ {0x400020116, 0x10, 0x100, 0x0, 0x10000}, - /* idx: 273 */ {0x400020116, 0x10, 0x100, 0x0, 0x20000}, - /* idx: 274 */ {0x400020116, 0x10, 0x200, 0x0, 0x40000}, - /* idx: 275 */ {0x400020116, 0x10, 0x200, 0x0, 0x80000}, - /* idx: 276 */ {0x400020116, 0x20, 0x400, 0x0, 0x100000}, - /* idx: 277 */ {0x400020116, 0x20, 0x400, 0x0, 0x200000}, - /* idx: 278 */ {0x400020116, 0x20, 0x800, 0x0, 0x400000}, - /* idx: 279 */ {0x400020116, 0x20, 0x800, 0x0, 0x800000}, - /* idx: 280 */ {0x800020116, 0x40, 0x1000, 0x0, 0x1000000}, - /* idx: 281 */ {0x800020116, 0x40, 0x1000, 0x0, 0x2000000}, - /* idx: 282 */ {0x800020116, 0x40, 0x2000, 0x0, 0x4000000}, - /* idx: 283 */ {0x800020116, 0x40, 0x2000, 0x0, 0x8000000}, - /* idx: 284 */ {0x800020116, 0x80, 0x4000, 0x0, 0x10000000}, - /* idx: 285 */ {0x800020116, 0x80, 0x4000, 0x0, 0x20000000}, - /* idx: 286 */ {0x800020116, 0x80, 0x8000, 0x0, 0x40000000}, - /* idx: 287 */ {0x800020116, 0x80, 0x8000, 0x0, 0x80000000}, - /* idx: 288 */ {0x1000040216, 0x100, 0x10000, 0x0, 0x100000000}, - /* idx: 289 */ {0x1000040216, 0x100, 0x10000, 0x0, 0x200000000}, - /* idx: 290 */ {0x1000040216, 0x100, 0x20000, 0x0, 0x400000000}, - /* idx: 291 */ {0x1000040216, 0x100, 0x20000, 0x0, 0x800000000}, - /* idx: 292 */ {0x1000040216, 0x200, 0x40000, 0x0, 0x1000000000}, - /* idx: 293 */ {0x1000040216, 0x200, 0x40000, 0x0, 0x2000000000}, - /* idx: 294 */ {0x1000040216, 0x200, 0x80000, 0x0, 0x4000000000}, - /* idx: 295 */ {0x1000040216, 0x200, 0x80000, 0x0, 0x8000000000}, - /* idx: 296 */ {0x2000040216, 0x400, 0x100000, 0x0, 0x10000000000}, - /* idx: 297 */ {0x2000040216, 0x400, 0x100000, 0x0, 0x20000000000}, - /* idx: 298 */ {0x2000040216, 0x400, 0x200000, 0x0, 0x40000000000}, - /* idx: 299 */ {0x2000040216, 0x400, 0x200000, 0x0, 0x80000000000}, - /* idx: 300 */ {0x2000040216, 0x800, 0x400000, 0x0, 0x100000000000}, - /* idx: 301 */ {0x2000040216, 0x800, 0x400000, 0x0, 0x200000000000}, - /* idx: 302 */ {0x2000040216, 0x800, 0x800000, 0x0, 0x400000000000}, - /* idx: 303 */ {0x2000040216, 0x800, 0x800000, 0x0, 0x800000000000}, - /* idx: 304 */ {0x4000080216, 0x1000, 0x1000000, 0x0, 0x1000000000000}, - /* idx: 305 */ {0x4000080216, 0x1000, 0x1000000, 0x0, 0x2000000000000}, - /* idx: 306 */ {0x4000080216, 0x1000, 0x2000000, 0x0, 0x4000000000000}, - /* idx: 307 */ {0x4000080216, 0x1000, 0x2000000, 0x0, 0x8000000000000}, - /* idx: 308 */ {0x4000080216, 0x2000, 0x4000000, 0x0, 0x10000000000000}, - /* idx: 309 */ {0x4000080216, 0x2000, 0x4000000, 0x0, 0x20000000000000}, - /* idx: 310 */ {0x4000080216, 0x2000, 0x8000000, 0x0, 0x40000000000000}, - /* idx: 311 */ {0x4000080216, 0x2000, 0x8000000, 0x0, 0x80000000000000}, - /* idx: 312 */ {0x8000080216, 0x4000, 0x10000000, 0x0, 0x100000000000000}, - /* idx: 313 */ {0x8000080216, 0x4000, 0x10000000, 0x0, 0x200000000000000}, - /* idx: 314 */ {0x8000080216, 0x4000, 0x20000000, 0x0, 0x400000000000000}, - /* idx: 315 */ {0x8000080216, 0x4000, 0x20000000, 0x0, 0x800000000000000}, - /* idx: 316 */ {0x8000080216, 0x8000, 0x40000000, 0x0, 0x1000000000000000}, - /* idx: 317 */ {0x8000080216, 0x8000, 0x40000000, 0x0, 0x2000000000000000}, - /* idx: 318 */ {0x8000080216, 0x8000, 0x80000000, 0x0, 0x4000000000000000}, - /* idx: 319 */ {0x8000080216, 0x8000, 0x80000000, 0x0, 0x8000000000000000}, - /* idx: 320 */ {0x10000100426, 0x10000, 0x100000000, 0x0, 0x0, 0x1}, - /* idx: 321 */ {0x10000100426, 0x10000, 0x100000000, 0x0, 0x0, 0x2}, - /* idx: 322 */ {0x10000100426, 0x10000, 0x200000000, 0x0, 0x0, 0x4}, - /* idx: 323 */ {0x10000100426, 0x10000, 0x200000000, 0x0, 0x0, 0x8}, - /* idx: 324 */ {0x10000100426, 0x20000, 0x400000000, 0x0, 0x0, 0x10}, - /* idx: 325 */ {0x10000100426, 0x20000, 0x400000000, 0x0, 0x0, 0x20}, - /* idx: 326 */ {0x10000100426, 0x20000, 0x800000000, 0x0, 0x0, 0x40}, - /* idx: 327 */ {0x10000100426, 0x20000, 0x800000000, 0x0, 0x0, 0x80}, - /* idx: 328 */ {0x20000100426, 0x40000, 0x1000000000, 0x0, 0x0, 0x100}, - /* idx: 329 */ {0x20000100426, 0x40000, 0x1000000000, 0x0, 0x0, 0x200}, - /* idx: 330 */ {0x20000100426, 0x40000, 0x2000000000, 0x0, 0x0, 0x400}, - /* idx: 331 */ {0x20000100426, 0x40000, 0x2000000000, 0x0, 0x0, 0x800}, - /* idx: 332 */ {0x20000100426, 0x80000, 0x4000000000, 0x0, 0x0, 0x1000}, - /* idx: 333 */ {0x20000100426, 0x80000, 0x4000000000, 0x0, 0x0, 0x2000}, - /* idx: 334 */ {0x20000100426, 0x80000, 0x8000000000, 0x0, 0x0, 0x4000}, - /* idx: 335 */ {0x20000100426, 0x80000, 0x8000000000, 0x0, 0x0, 0x8000}, - /* idx: 336 */ {0x40000200426, 0x100000, 0x10000000000, 0x0, 0x0, 0x10000}, - /* idx: 337 */ {0x40000200426, 0x100000, 0x10000000000, 0x0, 0x0, 0x20000}, - /* idx: 338 */ {0x40000200426, 0x100000, 0x20000000000, 0x0, 0x0, 0x40000}, - /* idx: 339 */ {0x40000200426, 0x100000, 0x20000000000, 0x0, 0x0, 0x80000}, - /* idx: 340 */ {0x40000200426, 0x200000, 0x40000000000, 0x0, 0x0, 0x100000}, - /* idx: 341 */ {0x40000200426, 0x200000, 0x40000000000, 0x0, 0x0, 0x200000}, - /* idx: 342 */ {0x40000200426, 0x200000, 0x80000000000, 0x0, 0x0, 0x400000}, - /* idx: 343 */ {0x40000200426, 0x200000, 0x80000000000, 0x0, 0x0, 0x800000}, - /* idx: 344 */ {0x80000200426, 0x400000, 0x100000000000, 0x0, 0x0, 0x1000000}, - /* idx: 345 */ {0x80000200426, 0x400000, 0x100000000000, 0x0, 0x0, 0x2000000}, - /* idx: 346 */ {0x80000200426, 0x400000, 0x200000000000, 0x0, 0x0, 0x4000000}, - /* idx: 347 */ {0x80000200426, 0x400000, 0x200000000000, 0x0, 0x0, 0x8000000}, - /* idx: 348 */ {0x80000200426, 0x800000, 0x400000000000, 0x0, 0x0, 0x10000000}, - /* idx: 349 */ {0x80000200426, 0x800000, 0x400000000000, 0x0, 0x0, 0x20000000}, - /* idx: 350 */ {0x80000200426, 0x800000, 0x800000000000, 0x0, 0x0, 0x40000000}, - /* idx: 351 */ {0x80000200426, 0x800000, 0x800000000000, 0x0, 0x0, 0x80000000}, - /* idx: 352 */ {0x100000400826, 0x1000000, 0x1000000000000, 0x0, 0x0, 0x100000000}, - /* idx: 353 */ {0x100000400826, 0x1000000, 0x1000000000000, 0x0, 0x0, 0x200000000}, - /* idx: 354 */ {0x100000400826, 0x1000000, 0x2000000000000, 0x0, 0x0, 0x400000000}, - /* idx: 355 */ {0x100000400826, 0x1000000, 0x2000000000000, 0x0, 0x0, 0x800000000}, - /* idx: 356 */ {0x100000400826, 0x2000000, 0x4000000000000, 0x0, 0x0, 0x1000000000}, - /* idx: 357 */ {0x100000400826, 0x2000000, 0x4000000000000, 0x0, 0x0, 0x2000000000}, - /* idx: 358 */ {0x100000400826, 0x2000000, 0x8000000000000, 0x0, 0x0, 0x4000000000}, - /* idx: 359 */ {0x100000400826, 0x2000000, 0x8000000000000, 0x0, 0x0, 0x8000000000}, - /* idx: 360 */ {0x200000400826, 0x4000000, 0x10000000000000, 0x0, 0x0, 0x10000000000}, - /* idx: 361 */ {0x200000400826, 0x4000000, 0x10000000000000, 0x0, 0x0, 0x20000000000}, - /* idx: 362 */ {0x200000400826, 0x4000000, 0x20000000000000, 0x0, 0x0, 0x40000000000}, - /* idx: 363 */ {0x200000400826, 0x4000000, 0x20000000000000, 0x0, 0x0, 0x80000000000}, - /* idx: 364 */ {0x200000400826, 0x8000000, 0x40000000000000, 0x0, 0x0, 0x100000000000}, - /* idx: 365 */ {0x200000400826, 0x8000000, 0x40000000000000, 0x0, 0x0, 0x200000000000}, - /* idx: 366 */ {0x200000400826, 0x8000000, 0x80000000000000, 0x0, 0x0, 0x400000000000}, - /* idx: 367 */ {0x200000400826, 0x8000000, 0x80000000000000, 0x0, 0x0, 0x800000000000}, - /* idx: 368 */ {0x400000800826, 0x10000000, 0x100000000000000, 0x0, 0x0, 0x1000000000000}, - /* idx: 369 */ {0x400000800826, 0x10000000, 0x100000000000000, 0x0, 0x0, 0x2000000000000}, - /* idx: 370 */ {0x400000800826, 0x10000000, 0x200000000000000, 0x0, 0x0, 0x4000000000000}, - /* idx: 371 */ {0x400000800826, 0x10000000, 0x200000000000000, 0x0, 0x0, 0x8000000000000}, - /* idx: 372 */ {0x400000800826, 0x20000000, 0x400000000000000, 0x0, 0x0, 0x10000000000000}, - /* idx: 373 */ {0x400000800826, 0x20000000, 0x400000000000000, 0x0, 0x0, 0x20000000000000}, - /* idx: 374 */ {0x400000800826, 0x20000000, 0x800000000000000, 0x0, 0x0, 0x40000000000000}, - /* idx: 375 */ {0x400000800826, 0x20000000, 0x800000000000000, 0x0, 0x0, 0x80000000000000}, - /* idx: 376 */ {0x800000800826, 0x40000000, 0x1000000000000000, 0x0, 0x0, 0x100000000000000}, - /* idx: 377 */ {0x800000800826, 0x40000000, 0x1000000000000000, 0x0, 0x0, 0x200000000000000}, - /* idx: 378 */ {0x800000800826, 0x40000000, 0x2000000000000000, 0x0, 0x0, 0x400000000000000}, - /* idx: 379 */ {0x800000800826, 0x40000000, 0x2000000000000000, 0x0, 0x0, 0x800000000000000}, - /* idx: 380 */ {0x800000800826, 0x80000000, 0x4000000000000000, 0x0, 0x0, 0x1000000000000000}, - /* idx: 381 */ {0x800000800826, 0x80000000, 0x4000000000000000, 0x0, 0x0, 0x2000000000000000}, - /* idx: 382 */ {0x800000800826, 0x80000000, 0x8000000000000000, 0x0, 0x0, 0x4000000000000000}, - /* idx: 383 */ {0x800000800826, 0x80000000, 0x8000000000000000, 0x0, 0x0, 0x8000000000000000}, - /* idx: 384 */ {0x100000100104a, 0x100000000, 0x0, 0x1, 0x0, 0x0, 0x1}, - /* idx: 385 */ {0x100000100104a, 0x100000000, 0x0, 0x1, 0x0, 0x0, 0x2}, - /* idx: 386 */ {0x100000100104a, 0x100000000, 0x0, 0x2, 0x0, 0x0, 0x4}, - /* idx: 387 */ {0x100000100104a, 0x100000000, 0x0, 0x2, 0x0, 0x0, 0x8}, - /* idx: 388 */ {0x100000100104a, 0x200000000, 0x0, 0x4, 0x0, 0x0, 0x10}, - /* idx: 389 */ {0x100000100104a, 0x200000000, 0x0, 0x4, 0x0, 0x0, 0x20}, - /* idx: 390 */ {0x100000100104a, 0x200000000, 0x0, 0x8, 0x0, 0x0, 0x40}, - /* idx: 391 */ {0x100000100104a, 0x200000000, 0x0, 0x8, 0x0, 0x0, 0x80}, - /* idx: 392 */ {0x200000100104a, 0x400000000, 0x0, 0x10, 0x0, 0x0, 0x100}, - /* idx: 393 */ {0x200000100104a, 0x400000000, 0x0, 0x10, 0x0, 0x0, 0x200}, - /* idx: 394 */ {0x200000100104a, 0x400000000, 0x0, 0x20, 0x0, 0x0, 0x400}, - /* idx: 395 */ {0x200000100104a, 0x400000000, 0x0, 0x20, 0x0, 0x0, 0x800}, - /* idx: 396 */ {0x200000100104a, 0x800000000, 0x0, 0x40, 0x0, 0x0, 0x1000}, - /* idx: 397 */ {0x200000100104a, 0x800000000, 0x0, 0x40, 0x0, 0x0, 0x2000}, - /* idx: 398 */ {0x200000100104a, 0x800000000, 0x0, 0x80, 0x0, 0x0, 0x4000}, - /* idx: 399 */ {0x200000100104a, 0x800000000, 0x0, 0x80, 0x0, 0x0, 0x8000}, - /* idx: 400 */ {0x400000200104a, 0x1000000000, 0x0, 0x100, 0x0, 0x0, 0x10000}, - /* idx: 401 */ {0x400000200104a, 0x1000000000, 0x0, 0x100, 0x0, 0x0, 0x20000}, - /* idx: 402 */ {0x400000200104a, 0x1000000000, 0x0, 0x200, 0x0, 0x0, 0x40000}, - /* idx: 403 */ {0x400000200104a, 0x1000000000, 0x0, 0x200, 0x0, 0x0, 0x80000}, - /* idx: 404 */ {0x400000200104a, 0x2000000000, 0x0, 0x400, 0x0, 0x0, 0x100000}, - /* idx: 405 */ {0x400000200104a, 0x2000000000, 0x0, 0x400, 0x0, 0x0, 0x200000}, - /* idx: 406 */ {0x400000200104a, 0x2000000000, 0x0, 0x800, 0x0, 0x0, 0x400000}, - /* idx: 407 */ {0x400000200104a, 0x2000000000, 0x0, 0x800, 0x0, 0x0, 0x800000}, - /* idx: 408 */ {0x800000200104a, 0x4000000000, 0x0, 0x1000, 0x0, 0x0, 0x1000000}, - /* idx: 409 */ {0x800000200104a, 0x4000000000, 0x0, 0x1000, 0x0, 0x0, 0x2000000}, - /* idx: 410 */ {0x800000200104a, 0x4000000000, 0x0, 0x2000, 0x0, 0x0, 0x4000000}, - /* idx: 411 */ {0x800000200104a, 0x4000000000, 0x0, 0x2000, 0x0, 0x0, 0x8000000}, - /* idx: 412 */ {0x800000200104a, 0x8000000000, 0x0, 0x4000, 0x0, 0x0, 0x10000000}, - /* idx: 413 */ {0x800000200104a, 0x8000000000, 0x0, 0x4000, 0x0, 0x0, 0x20000000}, - /* idx: 414 */ {0x800000200104a, 0x8000000000, 0x0, 0x8000, 0x0, 0x0, 0x40000000}, - /* idx: 415 */ {0x800000200104a, 0x8000000000, 0x0, 0x8000, 0x0, 0x0, 0x80000000}, - /* idx: 416 */ {0x1000000400204a, 0x10000000000, 0x0, 0x10000, 0x0, 0x0, 0x100000000}, - /* idx: 417 */ {0x1000000400204a, 0x10000000000, 0x0, 0x10000, 0x0, 0x0, 0x200000000}, - /* idx: 418 */ {0x1000000400204a, 0x10000000000, 0x0, 0x20000, 0x0, 0x0, 0x400000000}, - /* idx: 419 */ {0x1000000400204a, 0x10000000000, 0x0, 0x20000, 0x0, 0x0, 0x800000000}, - /* idx: 420 */ {0x1000000400204a, 0x20000000000, 0x0, 0x40000, 0x0, 0x0, 0x1000000000}, - /* idx: 421 */ {0x1000000400204a, 0x20000000000, 0x0, 0x40000, 0x0, 0x0, 0x2000000000}, - /* idx: 422 */ {0x1000000400204a, 0x20000000000, 0x0, 0x80000, 0x0, 0x0, 0x4000000000}, - /* idx: 423 */ {0x1000000400204a, 0x20000000000, 0x0, 0x80000, 0x0, 0x0, 0x8000000000}, - /* idx: 424 */ {0x2000000400204a, 0x40000000000, 0x0, 0x100000, 0x0, 0x0, 0x10000000000}, - /* idx: 425 */ {0x2000000400204a, 0x40000000000, 0x0, 0x100000, 0x0, 0x0, 0x20000000000}, - /* idx: 426 */ {0x2000000400204a, 0x40000000000, 0x0, 0x200000, 0x0, 0x0, 0x40000000000}, - /* idx: 427 */ {0x2000000400204a, 0x40000000000, 0x0, 0x200000, 0x0, 0x0, 0x80000000000}, - /* idx: 428 */ {0x2000000400204a, 0x80000000000, 0x0, 0x400000, 0x0, 0x0, 0x100000000000}, - /* idx: 429 */ {0x2000000400204a, 0x80000000000, 0x0, 0x400000, 0x0, 0x0, 0x200000000000}, - /* idx: 430 */ {0x2000000400204a, 0x80000000000, 0x0, 0x800000, 0x0, 0x0, 0x400000000000}, - /* idx: 431 */ {0x2000000400204a, 0x80000000000, 0x0, 0x800000, 0x0, 0x0, 0x800000000000}, - /* idx: 432 */ {0x4000000800204a, 0x100000000000, 0x0, 0x1000000, 0x0, 0x0, 0x1000000000000}, - /* idx: 433 */ {0x4000000800204a, 0x100000000000, 0x0, 0x1000000, 0x0, 0x0, 0x2000000000000}, - /* idx: 434 */ {0x4000000800204a, 0x100000000000, 0x0, 0x2000000, 0x0, 0x0, 0x4000000000000}, - /* idx: 435 */ {0x4000000800204a, 0x100000000000, 0x0, 0x2000000, 0x0, 0x0, 0x8000000000000}, - /* idx: 436 */ {0x4000000800204a, 0x200000000000, 0x0, 0x4000000, 0x0, 0x0, 0x10000000000000}, - /* idx: 437 */ {0x4000000800204a, 0x200000000000, 0x0, 0x4000000, 0x0, 0x0, 0x20000000000000}, - /* idx: 438 */ {0x4000000800204a, 0x200000000000, 0x0, 0x8000000, 0x0, 0x0, 0x40000000000000}, - /* idx: 439 */ {0x4000000800204a, 0x200000000000, 0x0, 0x8000000, 0x0, 0x0, 0x80000000000000}, - /* idx: 440 */ {0x8000000800204a, 0x400000000000, 0x0, 0x10000000, 0x0, 0x0, 0x100000000000000}, - /* idx: 441 */ {0x8000000800204a, 0x400000000000, 0x0, 0x10000000, 0x0, 0x0, 0x200000000000000}, - /* idx: 442 */ {0x8000000800204a, 0x400000000000, 0x0, 0x20000000, 0x0, 0x0, 0x400000000000000}, - /* idx: 443 */ {0x8000000800204a, 0x400000000000, 0x0, 0x20000000, 0x0, 0x0, 0x800000000000000}, - /* idx: 444 */ {0x8000000800204a, 0x800000000000, 0x0, 0x40000000, 0x0, 0x0, 0x1000000000000000}, - /* idx: 445 */ {0x8000000800204a, 0x800000000000, 0x0, 0x40000000, 0x0, 0x0, 0x2000000000000000}, - /* idx: 446 */ {0x8000000800204a, 0x800000000000, 0x0, 0x80000000, 0x0, 0x0, 0x4000000000000000}, - /* idx: 447 */ {0x8000000800204a, 0x800000000000, 0x0, 0x80000000, 0x0, 0x0, 0x8000000000000000}, - /* idx: 448 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x1}, - /* idx: 449 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x2}, - /* idx: 450 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x200000000, 0x0, 0x0, 0x0, 0x4}, - /* idx: 451 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x200000000, 0x0, 0x0, 0x0, 0x8}, - /* idx: 452 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x400000000, 0x0, 0x0, 0x0, 0x10}, - /* idx: 453 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x400000000, 0x0, 0x0, 0x0, 0x20}, - /* idx: 454 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x800000000, 0x0, 0x0, 0x0, 0x40}, - /* idx: 455 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x800000000, 0x0, 0x0, 0x0, 0x80}, - /* idx: 456 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x1000000000, 0x0, 0x0, 0x0, 0x100}, - /* idx: 457 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x1000000000, 0x0, 0x0, 0x0, 0x200}, - /* idx: 458 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x2000000000, 0x0, 0x0, 0x0, 0x400}, - /* idx: 459 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x2000000000, 0x0, 0x0, 0x0, 0x800}, - /* idx: 460 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x4000000000, 0x0, 0x0, 0x0, 0x1000}, - /* idx: 461 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x4000000000, 0x0, 0x0, 0x0, 0x2000}, - /* idx: 462 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x8000000000, 0x0, 0x0, 0x0, 0x4000}, - /* idx: 463 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x8000000000, 0x0, 0x0, 0x0, 0x8000}, - /* idx: 464 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x10000000000, 0x0, 0x0, 0x0, 0x10000}, - /* idx: 465 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x10000000000, 0x0, 0x0, 0x0, 0x20000}, - /* idx: 466 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x20000000000, 0x0, 0x0, 0x0, 0x40000}, - /* idx: 467 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x20000000000, 0x0, 0x0, 0x0, 0x80000}, - /* idx: 468 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x40000000000, 0x0, 0x0, 0x0, 0x100000}, - /* idx: 469 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x40000000000, 0x0, 0x0, 0x0, 0x200000}, - /* idx: 470 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x80000000000, 0x0, 0x0, 0x0, 0x400000}, - /* idx: 471 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x80000000000, 0x0, 0x0, 0x0, 0x800000}, - /* idx: 472 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x100000000000, 0x0, 0x0, 0x0, 0x1000000}, - /* idx: 473 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x100000000000, 0x0, 0x0, 0x0, 0x2000000}, - /* idx: 474 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x200000000000, 0x0, 0x0, 0x0, 0x4000000}, - /* idx: 475 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x200000000000, 0x0, 0x0, 0x0, 0x8000000}, - /* idx: 476 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x400000000000, 0x0, 0x0, 0x0, 0x10000000}, - /* idx: 477 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x400000000000, 0x0, 0x0, 0x0, 0x20000000}, - /* idx: 478 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x800000000000, 0x0, 0x0, 0x0, 0x40000000}, - /* idx: 479 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x800000000000, 0x0, 0x0, 0x0, 0x80000000}, - /* idx: 480 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x1000000000000, 0x0, 0x0, 0x0, 0x100000000}, - /* idx: 481 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x1000000000000, 0x0, 0x0, 0x0, 0x200000000}, - /* idx: 482 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x2000000000000, 0x0, 0x0, 0x0, 0x400000000}, - /* idx: 483 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x2000000000000, 0x0, 0x0, 0x0, 0x800000000}, - /* idx: 484 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x4000000000000, 0x0, 0x0, 0x0, 0x1000000000}, - /* idx: 485 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x4000000000000, 0x0, 0x0, 0x0, 0x2000000000}, - /* idx: 486 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x8000000000000, 0x0, 0x0, 0x0, 0x4000000000}, - /* idx: 487 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x8000000000000, 0x0, 0x0, 0x0, 0x8000000000}, - /* idx: 488 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x10000000000000, 0x0, 0x0, 0x0, 0x10000000000}, - /* idx: 489 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x10000000000000, 0x0, 0x0, 0x0, 0x20000000000}, - /* idx: 490 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0x40000000000}, - /* idx: 491 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0x80000000000}, - /* idx: 492 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x40000000000000, 0x0, 0x0, 0x0, 0x100000000000}, - /* idx: 493 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x40000000000000, 0x0, 0x0, 0x0, 0x200000000000}, - /* idx: 494 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x80000000000000, 0x0, 0x0, 0x0, 0x400000000000}, - /* idx: 495 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x80000000000000, 0x0, 0x0, 0x0, 0x800000000000}, - /* idx: 496 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x100000000000000, 0x0, 0x0, 0x0, 0x1000000000000}, - /* idx: 497 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x100000000000000, 0x0, 0x0, 0x0, 0x2000000000000}, - /* idx: 498 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x200000000000000, 0x0, 0x0, 0x0, 0x4000000000000}, - /* idx: 499 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x200000000000000, 0x0, 0x0, 0x0, 0x8000000000000}, - /* idx: 500 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x400000000000000, 0x0, 0x0, 0x0, 0x10000000000000}, - /* idx: 501 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x400000000000000, 0x0, 0x0, 0x0, 0x20000000000000}, - /* idx: 502 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x800000000000000, 0x0, 0x0, 0x0, 0x40000000000000}, - /* idx: 503 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x800000000000000, 0x0, 0x0, 0x0, 0x80000000000000}, - /* idx: 504 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x1000000000000000, 0x0, 0x0, 0x0, 0x100000000000000}, - /* idx: 505 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x1000000000000000, 0x0, 0x0, 0x0, 0x200000000000000}, - /* idx: 506 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x2000000000000000, 0x0, 0x0, 0x0, 0x400000000000000}, - /* idx: 507 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x2000000000000000, 0x0, 0x0, 0x0, 0x800000000000000}, - /* idx: 508 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x4000000000000000, 0x0, 0x0, 0x0, 0x1000000000000000}, - /* idx: 509 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x4000000000000000, 0x0, 0x0, 0x0, 0x2000000000000000}, - /* idx: 510 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x8000000000000000, 0x0, 0x0, 0x0, 0x4000000000000000}, - /* idx: 511 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x8000000000000000, 0x0, 0x0, 0x0, 0x8000000000000000}, -} diff --git a/vendor/github.com/gaissmai/bart/node.go b/vendor/github.com/gaissmai/bart/node.go deleted file mode 100644 index 15bf12c..0000000 --- a/vendor/github.com/gaissmai/bart/node.go +++ /dev/null @@ -1,729 +0,0 @@ -// Copyright (c) 2024 Karl Gaissmaier -// SPDX-License-Identifier: MIT - -package bart - -import ( - "net/netip" - "slices" - - "github.com/gaissmai/bart/internal/sparse" -) - -const ( - strideLen = 8 // octet - maxTreeDepth = 16 // 16 for IPv6 - maxNodeChildren = 256 // 256 - maxNodePrefixes = 512 // 512 -) - -// stridePath, max 16 octets deep -type stridePath [maxTreeDepth]uint8 - -// node is a level node in the multibit-trie. -// A node has prefixes and children, forming the multibit trie. -// -// The prefixes form a complete binary tree, see the artlookup.pdf -// paper in the doc folder to understand the data structure. -// -// In contrast to the ART algorithm, sparse arrays -// (popcount-compressed slices) are used instead of fixed-size arrays. -// -// The array slots are also not pre-allocated (alloted) as described -// in the ART algorithm, fast backtracking with a bitset vector is used -// to get the longest-prefix-match. -// -// The sparse child array recursively spans the trie with a branching factor of 256 -// and also records path-compressed leaves in the free node slots. -type node[V any] struct { - // prefixes contains the routes indexed as a complete binary tree with payload V - // with the help of the baseIndex function from the ART algorithm. - prefixes sparse.Array[V] - - // children, recursively spans the trie with a branching factor of 256. - // - // Sorry, here we have to use a mixture of generics and interfaces: - // - // Without path compression, the definition would naturally be: - // children sparse.Array[*node[V]] - // - // ... but with path compression the child can now be a node or a path compressed leaf. - // - // With path compression we could define: - // type noder[V any] interface { - // isLeaf[V]() bool - // } - // - // and: - // children sparse.Array[noder[V]] - // - // But we use the empty interface{} instead, by intention, see below! - // - // The empty interface{} consumes less memory and type assertions are faster than - // indirect method calls like node.isLeaf() - children sparse.Array[interface{}] -} - -// isEmpty returns true if node has neither prefixes nor children -func (n *node[V]) isEmpty() bool { - return n.prefixes.Len() == 0 && n.children.Len() == 0 -} - -// leaf is a prefix with value, used as a path compressed child -type leaf[V any] struct { - prefix netip.Prefix - value V -} - -// cloneOrCopy, helper function, -// deep copy if v implements the Cloner interface. -func cloneOrCopy[V any](val V) V { - if cloner, ok := any(val).(Cloner[V]); ok { - return cloner.Clone() - } - // just a shallow copy - return val -} - -// cloneLeaf returns a clone of the leaf -// if the value implements the Cloner interface. -func (l *leaf[V]) cloneLeaf() *leaf[V] { - return &leaf[V]{l.prefix, cloneOrCopy(l.value)} -} - -// insertAtDepth insert a prefix/val into a node tree at depth. -// n must not be nil, prefix must be valid and already in canonical form. -// -// If a path compression has to be resolved because a new value is added -// that collides with a leaf, the compressed leaf is then reinserted -// one depth down in the node trie. -func (n *node[V]) insertAtDepth(pfx netip.Prefix, val V, depth int) (exists bool) { - ip := pfx.Addr() - bits := pfx.Bits() - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // find the proper trie node to insert prefix - // start with prefix octet at depth - for ; depth < len(octets); depth++ { - octet := octets[depth] - addr := uint(octet) - - // last significant octet: insert/override prefix/val into node - if depth == lastIdx { - return n.prefixes.InsertAt(pfxToIdx(octet, lastBits), val) - } - - if !n.children.Test(addr) { - // insert prefix path compressed - return n.children.InsertAt(addr, &leaf[V]{pfx, val}) - } - - // get the child: node or leaf - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue // descend down to next trie level - - case *leaf[V]: - // reached a path compressed prefix - // override value in slot if prefixes are equal - if kid.prefix == pfx { - kid.value = val - // exists - return true - } - - // create new node - // push the leaf down - // insert new child at current leaf position (addr) - // descend down, replace n with new child - newNode := new(node[V]) - newNode.insertAtDepth(kid.prefix, kid.value, depth+1) - - n.children.InsertAt(addr, newNode) - n = newNode - - default: - panic("logic error, wrong node type") - } - } - - panic("unreachable") -} - -// insertAtDepthPersist is the immutable version of insertAtDepth. -// All visited nodes are cloned during insertion. -func (n *node[V]) insertAtDepthPersist(pfx netip.Prefix, val V, depth int) (exists bool) { - ip := pfx.Addr() - bits := pfx.Bits() - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // find the proper trie node to insert prefix - // start with prefix octet at depth - for ; depth < len(octets); depth++ { - - octet := octets[depth] - addr := uint(octet) - - // last significant octet: insert/override prefix/val into node - if depth == lastIdx { - return n.prefixes.InsertAt(pfxToIdx(octet, lastBits), val) - } - - if !n.children.Test(addr) { - // insert new prefix path compressed - return n.children.InsertAt(addr, &leaf[V]{pfx, val}) - } - - // get the child: node or leaf, but clone the path down - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - // proceed to next level - kid = kid.cloneFlat() - n.children.InsertAt(addr, kid) - n = kid - continue // descend down to next trie level - - case *leaf[V]: - kid = kid.cloneLeaf() - - // override value in slot if prefixes are equal - if kid.prefix == pfx { - // exists - return n.children.InsertAt(addr, &leaf[V]{pfx, val}) - } - - // create new node - // push the leaf down - // insert new child at current leaf position (addr) - // descend down, replace n with new child - newNode := new(node[V]) - newNode.insertAtDepth(kid.prefix, kid.value, depth+1) - - n.children.InsertAt(addr, newNode) - n = newNode - - default: - panic("logic error, wrong node type") - } - } - - panic("unreachable") -} - -// purgeAndCompress, purge empty nodes or compress nodes with single prefix or leaf. -func (n *node[V]) purgeAndCompress(parentStack []*node[V], childPath []uint8, is4 bool) { - // unwind the stack - for i := len(parentStack) - 1; i >= 0; i-- { - parent := parentStack[i] - addr := uint(childPath[i]) - - pfxCount := n.prefixes.Len() - childCount := n.children.Len() - - switch { - case n.isEmpty(): - // purge empty node - parent.children.DeleteAt(addr) - - case pfxCount == 1 && childCount == 0: - // make leaf from prefix idx, shift leaf one level up - // and override current node with new leaf - idx, _ := n.prefixes.FirstSet() - val := n.prefixes.Items[0] - - path := stridePath{} - copy(path[:], childPath) - pfx := cidrFromPath(path, i+1, is4, idx) - - parent.children.InsertAt(addr, &leaf[V]{pfx, val}) - - case pfxCount == 0 && childCount == 1: - // if single child is a leaf, shift it up one level - // and override current node with this leaf - if leafPtr, ok := n.children.Items[0].(*leaf[V]); ok { - parent.children.InsertAt(addr, leafPtr) - } - } - - n = parent - } -} - -// lpmGet does a route lookup for idx in the 8-bit (stride) routing table -// at this depth and returns (baseIdx, value, true) if a matching -// longest prefix exists, or ok=false otherwise. -// -// The prefixes in the stride form a complete binary tree (CBT) using the baseIndex function. -// In contrast to the ART algorithm, I do not use an allotment approach but map -// the backtracking in the CBT by a bitset operation with a precalculated backtracking path -// for the respective idx. -func (n *node[V]) lpmGet(idx uint) (baseIdx uint, val V, ok bool) { - // top is the idx of the longest-prefix-match - if top, ok := n.prefixes.IntersectionTop(lpmLookupTbl[idx]); ok { - return top, n.prefixes.MustGet(top), true - } - - // not found (on this level) - return 0, val, false -} - -// lpmTest for faster lpm tests without value returns. -func (n *node[V]) lpmTest(idx uint) bool { - return n.prefixes.IntersectsAny(lpmLookupTbl[idx]) -} - -// cloneRec, clones the node recursive. -func (n *node[V]) cloneRec() *node[V] { - if n == nil { - return nil - } - - c := new(node[V]) - if n.isEmpty() { - return c - } - - // shallow - c.prefixes = *(n.prefixes.Copy()) - - _, isCloner := any(*new(V)).(Cloner[V]) - - // deep copy if V implements Cloner[V] - if isCloner { - for i, val := range c.prefixes.Items { - c.prefixes.Items[i] = cloneOrCopy(val) - } - } - - // shallow - c.children = *(n.children.Copy()) - - // deep copy of nodes and leaves - for i, kidAny := range c.children.Items { - switch kid := kidAny.(type) { - case *node[V]: - // clone the child node rec-descent - c.children.Items[i] = kid.cloneRec() - case *leaf[V]: - // deep copy if V implements Cloner[V] - c.children.Items[i] = kid.cloneLeaf() - - default: - panic("logic error, wrong node type") - } - } - - return c -} - -// cloneFlat, copies the node and clone the values in prefixes and path compressed leaves -// if V implements Cloner. Used in the various ...Persist functions. -func (n *node[V]) cloneFlat() *node[V] { - if n == nil { - return nil - } - - c := new(node[V]) - if n.isEmpty() { - return c - } - - // shallow copy - c.prefixes = *(n.prefixes.Copy()) - c.children = *(n.children.Copy()) - - if _, ok := any(*new(V)).(Cloner[V]); !ok { - // if V doesn't implement Cloner[V], return early - return c - } - - // deep copy of values in prefixes - for i, val := range c.prefixes.Items { - c.prefixes.Items[i] = cloneOrCopy(val) - } - - // deep copy of values in path compressed leaves - for i, kidAny := range c.children.Items { - if kidLeaf, ok := kidAny.(*leaf[V]); ok { - c.children.Items[i] = kidLeaf.cloneLeaf() - } - } - - return c -} - -// allRec runs recursive the trie, starting at this node and -// the yield function is called for each route entry with prefix and value. -// If the yield function returns false the recursion ends prematurely and the -// false value is propagated. -// -// The iteration order is not defined, just the simplest and fastest recursive implementation. -func (n *node[V]) allRec(path stridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { - // for all prefixes in this node do ... - allIndices := n.prefixes.AsSlice(make([]uint, 0, maxNodePrefixes)) - for _, idx := range allIndices { - cidr := cidrFromPath(path, depth, is4, idx) - - // callback for this prefix and val - if !yield(cidr, n.prefixes.MustGet(idx)) { - // early exit - return false - } - } - - // for all children (nodes and leaves) in this node do ... - allChildAddrs := n.children.AsSlice(make([]uint, 0, maxNodeChildren)) - for i, addr := range allChildAddrs { - switch kid := n.children.Items[i].(type) { - case *node[V]: - // rec-descent with this node - path[depth] = byte(addr) - if !kid.allRec(path, depth+1, is4, yield) { - // early exit - return false - } - case *leaf[V]: - // callback for this leaf - if !yield(kid.prefix, kid.value) { - // early exit - return false - } - - default: - panic("logic error, wrong node type") - } - } - - return true -} - -// allRecSorted runs recursive the trie, starting at node and -// the yield function is called for each route entry with prefix and value. -// The iteration is in prefix sort order. -// -// If the yield function returns false the recursion ends prematurely and the -// false value is propagated. -func (n *node[V]) allRecSorted(path stridePath, depth int, is4 bool, yield func(netip.Prefix, V) bool) bool { - // get slice of all child octets, sorted by addr - allChildAddrs := n.children.AsSlice(make([]uint, 0, maxNodeChildren)) - - // get slice of all indexes, sorted by idx - allIndices := n.prefixes.AsSlice(make([]uint, 0, maxNodePrefixes)) - - // sort indices in CIDR sort order - slices.SortFunc(allIndices, cmpIndexRank) - - childCursor := 0 - - // yield indices and childs in CIDR sort order - for _, pfxIdx := range allIndices { - pfxOctet, _ := idxToPfx(pfxIdx) - - // yield all childs before idx - for j := childCursor; j < len(allChildAddrs); j++ { - childAddr := allChildAddrs[j] - - if childAddr >= uint(pfxOctet) { - break - } - - // yield the node (rec-descent) or leaf - switch kid := n.children.Items[j].(type) { - case *node[V]: - path[depth] = byte(childAddr) - if !kid.allRecSorted(path, depth+1, is4, yield) { - return false - } - case *leaf[V]: - if !yield(kid.prefix, kid.value) { - return false - } - - default: - panic("logic error, wrong node type") - } - - childCursor++ - } - - // yield the prefix for this idx - cidr := cidrFromPath(path, depth, is4, pfxIdx) - // n.prefixes.Items[i] not possible after sorting allIndices - if !yield(cidr, n.prefixes.MustGet(pfxIdx)) { - return false - } - } - - // yield the rest of leaves and nodes (rec-descent) - for j := childCursor; j < len(allChildAddrs); j++ { - addr := allChildAddrs[j] - switch kid := n.children.Items[j].(type) { - case *node[V]: - path[depth] = byte(addr) - if !kid.allRecSorted(path, depth+1, is4, yield) { - return false - } - case *leaf[V]: - if !yield(kid.prefix, kid.value) { - return false - } - - default: - panic("logic error, wrong node type") - } - } - - return true -} - -// unionRec combines two nodes, changing the receiver node. -// If there are duplicate entries, the value is taken from the other node. -// Count duplicate entries to adjust the t.size struct members. -func (n *node[V]) unionRec(o *node[V], depth int) (duplicates int) { - // for all prefixes in other node do ... - allIndices := o.prefixes.AsSlice(make([]uint, 0, maxNodePrefixes)) - for i, oIdx := range allIndices { - // insert/overwrite prefix/value from oNode to nNode - exists := n.prefixes.InsertAt(oIdx, o.prefixes.Items[i]) - - // this prefix is duplicate in n and o - if exists { - duplicates++ - } - } - - // for all child addrs in other node do ... - allOtherChildAddrs := o.children.AsSlice(make([]uint, 0, maxNodeChildren)) -LOOP: - for i, addr := range allOtherChildAddrs { - // 6 possible combinations for this child and other child child - // - // THIS, OTHER: - // ---------- - // NULL, node <-- easy, insert at cloned node - // NULL, leaf <-- easy, insert at cloned leaf - // node, node <-- easy, union rec-descent - // node, leaf <-- easy, insert other cloned leaf at depth+1 - // leaf, node <-- complex, push this leaf down, union rec-descent - // leaf, leaf <-- complex, push this leaf down, insert other cloned leaf at depth+1 - // - // try to get child at same addr from n - thisChild, thisExists := n.children.Get(addr) - if !thisExists { - switch otherChild := o.children.Items[i].(type) { - - case *node[V]: // NULL, node - if !thisExists { - n.children.InsertAt(addr, otherChild.cloneRec()) - continue LOOP - } - - case *leaf[V]: // NULL, leaf - if !thisExists { - n.children.InsertAt(addr, otherChild.cloneLeaf()) - continue LOOP - } - - default: - panic("logic error, wrong node type") - } - } - - switch otherChild := o.children.Items[i].(type) { - - case *node[V]: - switch this := thisChild.(type) { - - case *node[V]: // node, node - // both childs have node in octet, call union rec-descent on child nodes - duplicates += this.unionRec(otherChild, depth+1) - continue LOOP - - case *leaf[V]: // leaf, node - // create new node - nc := new(node[V]) - - // push this leaf down - nc.insertAtDepth(this.prefix, this.value, depth+1) - - // insert new node at current addr - n.children.InsertAt(addr, nc) - - // union rec-descent new node with other node - duplicates += nc.unionRec(otherChild, depth+1) - continue LOOP - } - - case *leaf[V]: - switch this := thisChild.(type) { - - case *node[V]: // node, leaf - clonedLeaf := otherChild.cloneLeaf() - if this.insertAtDepth(clonedLeaf.prefix, clonedLeaf.value, depth+1) { - duplicates++ - } - continue LOOP - - case *leaf[V]: // leaf, leaf - // create new node - nc := new(node[V]) - - // push this leaf down - nc.insertAtDepth(this.prefix, this.value, depth+1) - - // insert at depth cloned leaf - clonedLeaf := otherChild.cloneLeaf() - if nc.insertAtDepth(clonedLeaf.prefix, clonedLeaf.value, depth+1) { - duplicates++ - } - - // insert the new node at current addr - n.children.InsertAt(addr, nc) - continue LOOP - } - - default: - panic("logic error, wrong node type") - } - } - - return duplicates -} - -// eachLookupPrefix does an all prefix match in the 8-bit (stride) routing table -// at this depth and calls yield() for any matching CIDR. -func (n *node[V]) eachLookupPrefix(octets []byte, depth int, is4 bool, pfxLen int, yield func(netip.Prefix, V) bool) (ok bool) { - if n.prefixes.Len() == 0 { - return true - } - - // octets as array, needed below more than once - var path stridePath - copy(path[:], octets) - - // backtracking the CBT - for idx := pfxToIdx(octets[depth], pfxLen); idx > 0; idx >>= 1 { - if n.prefixes.Test(idx) { - val := n.prefixes.MustGet(idx) - cidr := cidrFromPath(path, depth, is4, idx) - - if !yield(cidr, val) { - return false - } - } - } - - return true -} - -// eachSubnet calls yield() for any covered CIDR by parent prefix in natural CIDR sort order. -func (n *node[V]) eachSubnet(octets []byte, depth int, is4 bool, pfxLen int, yield func(netip.Prefix, V) bool) bool { - // octets as array, needed below more than once - var path stridePath - copy(path[:], octets) - - pfxFirstAddr := uint(octets[depth]) - pfxLastAddr := uint(octets[depth] | ^netMask(pfxLen)) - - // 1. collect all indices in n covered by prefix - - allCoveredIndices := make([]uint, 0, maxNodePrefixes) - for _, idx := range n.prefixes.AsSlice(make([]uint, 0, maxNodePrefixes)) { - thisOctet, thisPfxLen := idxToPfx(idx) - - thisFirstAddr := uint(thisOctet) - thisLastAddr := uint(thisOctet | ^netMask(thisPfxLen)) - - if thisFirstAddr >= pfxFirstAddr && thisLastAddr <= pfxLastAddr { - allCoveredIndices = append(allCoveredIndices, idx) - } - } - - // sort indices in CIDR sort order - slices.SortFunc(allCoveredIndices, cmpIndexRank) - - // 2. collect all covered child addrs by prefix - - allCoveredChildAddrs := make([]uint, 0, maxNodeChildren) - for _, addr := range n.children.AsSlice(make([]uint, 0, maxNodeChildren)) { - if addr >= pfxFirstAddr && addr <= pfxLastAddr { - allCoveredChildAddrs = append(allCoveredChildAddrs, addr) - } - } - - // 3. yield covered indices, pathcomp prefixes and childs in CIDR sort order - - addrCursor := 0 - - // yield indices and childs in CIDR sort order - for _, pfxIdx := range allCoveredIndices { - pfxOctet, _ := idxToPfx(pfxIdx) - - // yield all childs before idx - for j := addrCursor; j < len(allCoveredChildAddrs); j++ { - addr := allCoveredChildAddrs[j] - if addr >= uint(pfxOctet) { - break - } - - // yield the node or leaf? - switch kid := n.children.MustGet(addr).(type) { - - case *node[V]: - path[depth] = byte(addr) - if !kid.allRecSorted(path, depth+1, is4, yield) { - return false - } - - case *leaf[V]: - if !yield(kid.prefix, kid.value) { - return false - } - - default: - panic("logic error, wrong node type") - } - - addrCursor++ - } - - // yield the prefix for this idx - cidr := cidrFromPath(path, depth, is4, pfxIdx) - // n.prefixes.Items[i] not possible after sorting allIndices - if !yield(cidr, n.prefixes.MustGet(pfxIdx)) { - return false - } - } - - // yield the rest of leaves and nodes (rec-descent) - for _, addr := range allCoveredChildAddrs[addrCursor:] { - // yield the node or leaf? - switch kid := n.children.MustGet(addr).(type) { - - case *node[V]: - path[depth] = byte(addr) - if !kid.allRecSorted(path, depth+1, is4, yield) { - return false - } - - case *leaf[V]: - if !yield(kid.prefix, kid.value) { - return false - } - - default: - panic("logic error, wrong node type") - } - } - - return true -} diff --git a/vendor/github.com/gaissmai/bart/overlaps.go b/vendor/github.com/gaissmai/bart/overlaps.go deleted file mode 100644 index f0ce66f..0000000 --- a/vendor/github.com/gaissmai/bart/overlaps.go +++ /dev/null @@ -1,305 +0,0 @@ -package bart - -import ( - "net/netip" - - "github.com/gaissmai/bart/internal/bitset" -) - -// overlaps returns true if any IP in the nodes n or o overlaps. -func (n *node[V]) overlaps(o *node[V], depth int) bool { - nPfxCount := n.prefixes.Len() - oPfxCount := o.prefixes.Len() - - nChildCount := n.children.Len() - oChildCount := o.children.Len() - - // ############################## - // 1. Test if any routes overlaps - // ############################## - - // full cross check - if nPfxCount > 0 && oPfxCount > 0 { - if n.overlapsRoutes(o) { - return true - } - } - - // #################################### - // 2. Test if routes overlaps any child - // #################################### - - // swap nodes to help chance on its way, - // if the first call to expensive overlapsChildrenIn() is already true, - // if both orders are false it doesn't help either - if nChildCount > oChildCount { - n, o = o, n - - nPfxCount = n.prefixes.Len() - oPfxCount = o.prefixes.Len() - - nChildCount = n.children.Len() - oChildCount = o.children.Len() - } - - if nPfxCount > 0 && oChildCount > 0 { - if n.overlapsChildrenIn(o) { - return true - } - } - - // symmetric reverse - if oPfxCount > 0 && nChildCount > 0 { - if o.overlapsChildrenIn(n) { - return true - } - } - - // ########################################### - // 3. childs with same octet in nodes n and o - // ########################################### - - // stop condition, n or o have no childs - if nChildCount == 0 || oChildCount == 0 { - return false - } - - // stop condition, no child with identical octet in n and o - if !n.children.IntersectsAny(o.children.BitSet) { - return false - } - - return n.overlapsSameChildren(o, depth) -} - -// overlapsRoutes, test if n overlaps o prefixes and vice versa -func (n *node[V]) overlapsRoutes(o *node[V]) bool { - // some prefixes are identical, trivial overlap - if n.prefixes.IntersectsAny(o.prefixes.BitSet) { - return true - } - - // get the lowest idx (biggest prefix) - nFirstIdx, _ := n.prefixes.FirstSet() - oFirstIdx, _ := o.prefixes.FirstSet() - - // start with other min value, see ART algo - nIdx := oFirstIdx - oIdx := nFirstIdx - - // make full cross check - nOK := true - oOK := true - - // zip, range over n and o together to help chance on its way - for nOK || oOK { - if nOK { - // does any route in o overlap this prefix from n - if nIdx, nOK = n.prefixes.NextSet(nIdx); nOK { - if o.lpmTest(nIdx) { - return true - } - - nIdx++ - } - } - - if oOK { - // does any route in n overlap this prefix from o - if oIdx, oOK = o.prefixes.NextSet(oIdx); oOK { - if n.lpmTest(oIdx) { - return true - } - - oIdx++ - } - } - } - - return false -} - -// overlapsChildrenIn, test if prefixes in n overlaps child octets in o. -func (n *node[V]) overlapsChildrenIn(o *node[V]) bool { - pfxCount := n.prefixes.Len() - childCount := o.children.Len() - - // heuristic, compare benchmarks - // when will we range over the children and when will we do bitset calc? - magicNumber := 15 - doRange := childCount < magicNumber || pfxCount > magicNumber - - // do range over, not so many childs and maybe to many prefixes for other algo below - if doRange { - lowerBound, _ := n.prefixes.FirstSet() - for _, addr := range o.children.AsSlice(make([]uint, 0, maxNodeChildren)) { - idx := hostIndex(addr) - if idx < lowerBound { // lpm match impossible - continue - } - if n.lpmTest(idx) { - return true - } - } - - return false - } - - // do bitset intersection, alloted route table with child octets - // maybe to many childs for range over or not so many prefixes to - // build the alloted routing table from them - - // make allot table with prefixes as bitsets, bitsets are precalculated - // just union the bitsets to one bitset (allot table) for all prefixes - // in this node - prefixRoutes := bitset.BitSet(make([]uint64, 8)) - - allIndices := n.prefixes.AsSlice(make([]uint, 0, maxNodePrefixes)) - - for _, idx := range allIndices { - // get pre alloted bitset for idx - prefixRoutes.InPlaceUnion(allotLookupTbl[idx]) - } - - // clone a bitset without heap allocation - // shift-right children bitset by 256 (firstHostIndex) - c8 := make([]uint64, 8) - copy(c8[4:], o.children.BitSet) // 4*64= 256 - hostRoutes := bitset.BitSet(c8) - - return prefixRoutes.IntersectsAny(hostRoutes) -} - -// overlapsSameChildren, find same octets with bitset intersection. -func (n *node[V]) overlapsSameChildren(o *node[V], depth int) bool { - // clone a bitset without heap allocation - c4 := [4]uint64{} - copy(c4[:], n.children.BitSet) - nChildrenBitsetCloned := bitset.BitSet(c4[:]) - - // intersect in place the cloned child bitset from n with o - nChildrenBitsetCloned.InPlaceIntersection(o.children.BitSet) - - allCommonChildren := nChildrenBitsetCloned.AsSlice(make([]uint, 0, maxNodeChildren)) - - // range over all child addrs, common in n and o - for _, addr := range allCommonChildren { - nChild := n.children.MustGet(addr) - oChild := o.children.MustGet(addr) - - if overlapsTwoChilds[V](nChild, oChild, depth+1) { - return true - } - } - - return false -} - -// overlapsTwoChilds, childs can be node or leaf. -func overlapsTwoChilds[V any](nChild, oChild any, depth int) bool { - // 4 possible different combinations for n and o - // - // node, node --> overlapsRec - // node, leaf --> overlapsPrefixAtDepth - // leaf, node --> overlapsPrefixAtDepth - // leaf, leaf --> netip.Prefix.Overlaps - // - switch nKind := nChild.(type) { - - case *node[V]: - switch oKind := oChild.(type) { - case *node[V]: // node, node - return nKind.overlaps(oKind, depth) - case *leaf[V]: // node, leaf - return nKind.overlapsPrefixAtDepth(oKind.prefix, depth) - } - - case *leaf[V]: - switch oKind := oChild.(type) { - case *node[V]: // leaf, node - return oKind.overlapsPrefixAtDepth(nKind.prefix, depth) - case *leaf[V]: // leaf, leaf - return oKind.prefix.Overlaps(nKind.prefix) - } - - default: - panic("logic error, wrong node type") - } - - return false -} - -// overlapsPrefixAtDepth, returns true if node overlaps with prefix -// starting with prefix octet at depth. -// -// Needed for path compressed prefix some level down in the node trie. -func (n *node[V]) overlapsPrefixAtDepth(pfx netip.Prefix, depth int) bool { - ip := pfx.Addr() - bits := pfx.Bits() - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - for ; depth < len(octets); depth++ { - octet := octets[depth] - addr := uint(octet) - - // full octet path in node trie, check overlap with last prefix octet - if depth == lastIdx { - return n.overlapsIdx(pfxToIdx(octet, lastBits)) - } - - // test if any route overlaps prefix´ so far - // no best match needed, forward tests without backtracking - if n.prefixes.Len() != 0 && n.lpmTest(hostIndex(addr)) { - return true - } - - if !n.children.Test(addr) { - return false - } - - // next child, node or leaf - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue - case *leaf[V]: - return kid.prefix.Overlaps(pfx) - - default: - panic("logic error, wrong node type") - } - } - - panic("unreachable: " + pfx.String()) -} - -// overlapsIdx returns true if node overlaps with prefix. -func (n *node[V]) overlapsIdx(idx uint) bool { - // 1. Test if any route in this node overlaps prefix? - if n.lpmTest(idx) { - return true - } - - // 2. Test if prefix overlaps any route in this node - - // use bitset intersections instead of range loops - // shallow copy pre alloted bitset for idx - allotedPrefixRoutes := allotLookupTbl[idx] - if allotedPrefixRoutes.IntersectsAny(n.prefixes.BitSet) { - return true - } - - // 3. Test if prefix overlaps any child in this node - - // shift-right children bitset by 256 (firstHostIndex) - c8 := [8]uint64{} - copy(c8[4:], n.children.BitSet) // 4*64= 256 - hostRoutes := bitset.BitSet(c8[:]) - - // use bitsets intersection instead of range loops - return allotedPrefixRoutes.IntersectsAny(hostRoutes) -} diff --git a/vendor/github.com/gaissmai/bart/stringify.go b/vendor/github.com/gaissmai/bart/stringify.go deleted file mode 100644 index 68b7dc0..0000000 --- a/vendor/github.com/gaissmai/bart/stringify.go +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright (c) 2024 Karl Gaissmaier -// SPDX-License-Identifier: MIT - -package bart - -import ( - "bytes" - "cmp" - "fmt" - "io" - "net/netip" - "slices" - "strings" -) - -// kid, a node has no path information about its predecessors, -// we collect this during the recursive descent. -// The path/depth/idx is needed to get the CIDR back. -type kid[V any] struct { - // for traversing - n *node[V] - is4 bool - path stridePath - depth int - idx uint - - // for printing - cidr netip.Prefix - val V -} - -// MarshalText implements the [encoding.TextMarshaler] interface, -// just a wrapper for [Table.Fprint]. -func (t *Table[V]) MarshalText() ([]byte, error) { - w := new(bytes.Buffer) - if err := t.Fprint(w); err != nil { - return nil, err - } - - return w.Bytes(), nil -} - -// String returns a hierarchical tree diagram of the ordered CIDRs -// as string, just a wrapper for [Table.Fprint]. -// If Fprint returns an error, String panics. -func (t *Table[V]) String() string { - w := new(strings.Builder) - if err := t.Fprint(w); err != nil { - panic(err) - } - - return w.String() -} - -// Fprint writes a hierarchical tree diagram of the ordered CIDRs -// with default formatted payload V to w. If w is nil, Fprint panics. -// -// The order from top to bottom is in ascending order of the prefix address -// and the subtree structure is determined by the CIDRs coverage. -// -// ▼ -// ├─ 10.0.0.0/8 (V) -// │ ├─ 10.0.0.0/24 (V) -// │ └─ 10.0.1.0/24 (V) -// ├─ 127.0.0.0/8 (V) -// │ └─ 127.0.0.1/32 (V) -// ├─ 169.254.0.0/16 (V) -// ├─ 172.16.0.0/12 (V) -// └─ 192.168.0.0/16 (V) -// └─ 192.168.1.0/24 (V) -// ▼ -// └─ ::/0 (V) -// ├─ ::1/128 (V) -// ├─ 2000::/3 (V) -// │ └─ 2001:db8::/32 (V) -// └─ fe80::/10 (V) -func (t *Table[V]) Fprint(w io.Writer) error { - // v4 - if err := t.fprint(w, true); err != nil { - return err - } - - // v6 - if err := t.fprint(w, false); err != nil { - return err - } - - return nil -} - -// fprint is the version dependent adapter to fprintRec. -func (t *Table[V]) fprint(w io.Writer, is4 bool) error { - n := t.rootNodeByVersion(is4) - if n.isEmpty() { - return nil - } - - if _, err := fmt.Fprint(w, "▼\n"); err != nil { - return err - } - - startKid := kid[V]{ - n: nil, - idx: 0, - path: stridePath{}, - is4: is4, - } - - if err := n.fprintRec(w, startKid, ""); err != nil { - return err - } - - return nil -} - -// fprintRec, the output is a hierarchical CIDR tree starting with this kid. -func (n *node[V]) fprintRec(w io.Writer, parent kid[V], pad string) error { - // recursion stop condition - if n == nil { - return nil - } - - // get direct childs for this kid ... - directKids := n.getKidsRec(parent.idx, parent.path, parent.depth, parent.is4) - - // sort them by netip.Prefix, not by baseIndex - slices.SortFunc(directKids, cmpKidByPrefix[V]) - - // symbols used in tree - glyphe := "├─ " - spacer := "│ " - - // for all direct kids under this node ... - for i, kid := range directKids { - // ... treat last kid special - if i == len(directKids)-1 { - glyphe = "└─ " - spacer = " " - } - - // print prefix and val, padded with glyphe - if _, err := fmt.Fprintf(w, "%s%s (%v)\n", pad+glyphe, kid.cidr, kid.val); err != nil { - return err - } - - // rec-descent with this prefix as parentIdx. - // hierarchical nested tree view, two rec-descent functions - // work together to spoil the reader. - if err := kid.n.fprintRec(w, kid, pad+spacer); err != nil { - return err - } - } - - return nil -} - -// getKidsRec, returns the direct kids below path and parentIdx. -// It's a recursive monster together with printRec, -// you have to know the data structure by heart to understand this function! -// -// See the artlookup.pdf paper in the doc folder, -// the baseIndex function is the key. -func (n *node[V]) getKidsRec(parentIdx uint, path stridePath, depth int, is4 bool) []kid[V] { - // recursion stop condition - if n == nil { - return nil - } - - var directKids []kid[V] - - for _, idx := range n.prefixes.All() { - // parent or self, handled alreday in an upper stack frame. - if idx <= parentIdx { - continue - } - - // check if lpmIdx for this idx' parent is equal to parentIdx - lpmIdx, _, _ := n.lpmGet(idx >> 1) - - // if idx is directKid? - if lpmIdx == parentIdx { - cidr := cidrFromPath(path, depth, is4, idx) - - kid := kid[V]{ - n: n, - is4: is4, - path: path, - depth: depth, - idx: idx, - cidr: cidr, - val: n.prefixes.MustGet(idx), - } - - directKids = append(directKids, kid) - } - } - - // the node may have childs and leaves, the rec-descent monster starts - for i, addr := range n.children.All() { - // do a longest-prefix-match - lpmIdx, _, _ := n.lpmGet(hostIndex(addr)) - if lpmIdx == parentIdx { - switch k := n.children.Items[i].(type) { - case *node[V]: - path[depth] = byte(addr) - - // traverse, rec-descent call with next child node - directKids = append(directKids, k.getKidsRec(0, path, depth+1, is4)...) - case *leaf[V]: - kid := kid[V]{ - n: nil, // path compressed item, stop recursion - is4: is4, - cidr: k.prefix, - val: k.value, - } - - directKids = append(directKids, kid) - } - } - } - - return directKids -} - -// cmpKidByPrefix, all prefixes are already normalized (Masked). -func cmpKidByPrefix[V any](a, b kid[V]) int { - return cmpPrefix(a.cidr, b.cidr) -} - -// cmpPrefix, compare func for prefix sort, -// all cidrs are already normalized -func cmpPrefix(a, b netip.Prefix) int { - if cmp := a.Addr().Compare(b.Addr()); cmp != 0 { - return cmp - } - - return cmp.Compare(a.Bits(), b.Bits()) -} - -// cidrFromPath, get prefix back from byte path, depth, octet and pfxLen. -func cidrFromPath(path stridePath, depth int, is4 bool, idx uint) netip.Prefix { - octet, pfxLen := idxToPfx(idx) - - // set masked byte in path at depth - path[depth] = octet - - // zero/mask the bytes after prefix bits - clear(path[depth+1:]) - - // make ip addr from octets - var ip netip.Addr - if is4 { - ip = netip.AddrFrom4([4]byte(path[:4])) - } else { - ip = netip.AddrFrom16(path) - } - - // calc bits with pathLen and pfxLen - bits := depth<<3 + pfxLen - - // return a normalized prefix from ip/bits - return netip.PrefixFrom(ip, bits) -} diff --git a/vendor/github.com/gaissmai/bart/table.go b/vendor/github.com/gaissmai/bart/table.go deleted file mode 100644 index d9d356c..0000000 --- a/vendor/github.com/gaissmai/bart/table.go +++ /dev/null @@ -1,1131 +0,0 @@ -// SPDX-License-Identifier: MIT - -// package bart provides a Balanced-Routing-Table (BART). -// -// BART is balanced in terms of memory usage and lookup time -// for the longest-prefix match. -// -// BART is a multibit-trie with fixed stride length of 8 bits, -// using the _baseIndex_ function from the ART algorithm to -// build the complete-binary-tree (CBT) of prefixes for each stride. -// -// The CBT is implemented as a bit-vector, backtracking is just -// a matter of fast cache friendly bitmask operations. -// -// The routing table is implemented with popcount compressed sparse arrays -// together with path compression. This reduces storage consumption -// by almost two orders of magnitude in comparison to ART with -// similar lookup times for the longest prefix match. -package bart - -import ( - "iter" - "net/netip" -) - -// Table is an IPv4 and IPv6 routing table with payload V. -// The zero value is ready to use. -// -// The Table is safe for concurrent readers but not for concurrent readers -// and/or writers. Either the update operations must be protected by an -// external lock mechanism or the various ...Persist functions must be used -// which return a modified routing table by leaving the original unchanged -// -// A Table must not be copied by value, see [Table.Clone]. -type Table[V any] struct { - // used by -copylocks checker from `go vet`. - _ noCopy - - // the root nodes, implemented as popcount compressed multibit tries - root4 node[V] - root6 node[V] - - // the number of prefixes in the routing table - size4 int - size6 int -} - -// rootNodeByVersion, root node getter for ip version. -func (t *Table[V]) rootNodeByVersion(is4 bool) *node[V] { - if is4 { - return &t.root4 - } - - return &t.root6 -} - -// Insert adds pfx to the tree, with given val. -// If pfx is already present in the tree, its value is set to val. -func (t *Table[V]) Insert(pfx netip.Prefix, val V) { - if !pfx.IsValid() { - return - } - - // canonicalize prefix - pfx = pfx.Masked() - - is4 := pfx.Addr().Is4() - n := t.rootNodeByVersion(is4) - - if n.insertAtDepth(pfx, val, 0) { - return - } - - // true insert, update size - t.sizeUpdate(is4, 1) -} - -// InsertPersist is similar to Insert but the receiver isn't modified. -// -// All nodes touched during insert are cloned and a new Table is returned. -// This is not a full [Table.Clone], all untouched nodes are still referenced -// from both Tables. -// -// If the payload V is a pointer or contains a pointer, it should -// implement the cloner interface. -// -// This is orders of magnitude slower than Insert (μsec versus nsec). -// -// The bulk table load should be done with [Table.Insert] and then you can -// use InsertPersist, [Table.UpdatePersist] and [Table.DeletePersist] for lock-free updates. -func (t *Table[V]) InsertPersist(pfx netip.Prefix, val V) *Table[V] { - if !pfx.IsValid() { - return t - } - - pt := &Table[V]{ - root4: t.root4, - root6: t.root6, - size4: t.size4, - size6: t.size6, - } - - // canonicalize prefix - pfx = pfx.Masked() - - is4 := pfx.Addr().Is4() - - n := pt.rootNodeByVersion(is4) - - // clone the root of insertion path - *n = *n.cloneFlat() - - // clone nodes along the insertion path - if n.insertAtDepthPersist(pfx, val, 0) { - // prefix existed, no size increment - return pt - } - - // true insert, update size - pt.sizeUpdate(is4, 1) - - return pt -} - -// Update or set the value at pfx with a callback function. -// The callback function is called with (value, ok) and returns a new value. -// -// If the pfx does not already exist, it is set with the new value. -func (t *Table[V]) Update(pfx netip.Prefix, cb func(val V, ok bool) V) (newVal V) { - var zero V - - if !pfx.IsValid() { - return zero - } - - // canonicalize prefix - pfx = pfx.Masked() - - // values derived from pfx - ip := pfx.Addr() - is4 := ip.Is4() - bits := pfx.Bits() - - n := t.rootNodeByVersion(is4) - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // find the proper trie node to update prefix - for depth, octet := range octets { - // last octet from prefix, update/insert prefix into node - if depth == lastIdx { - newVal, exists := n.prefixes.UpdateAt(pfxToIdx(octet, lastBits), cb) - if !exists { - t.sizeUpdate(is4, 1) - } - return newVal - } - - addr := uint(octet) - - // go down in tight loop to last octet - if !n.children.Test(addr) { - // insert prefix path compressed - newVal := cb(zero, false) - n.children.InsertAt(addr, &leaf[V]{pfx, newVal}) - t.sizeUpdate(is4, 1) - return newVal - } - - // get node or leaf for octet - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue // descend down to next trie level - - case *leaf[V]: - // update existing value if prefixes are equal - if kid.prefix == pfx { - kid.value = cb(kid.value, true) - return kid.value - } - - // create new node - // push the leaf down - // insert new child at current leaf position (addr) - // descend down, replace n with new child - newNode := new(node[V]) - newNode.insertAtDepth(kid.prefix, kid.value, depth+1) - - n.children.InsertAt(addr, newNode) - n = newNode - - default: - panic("logic error, wrong node type") - } - } - - panic("unreachable") -} - -// UpdatePersist is similar to Update but the receiver isn't modified. -// -// All nodes touched during update are cloned and a new Table is returned. -// This is not a full [Table.Clone], all untouched nodes are still referenced -// from both Tables. -// -// If the payload V is a pointer or contains a pointer, it should -// implement the cloner interface. -// -// This is orders of magnitude slower than Update (μsec versus nsec). -func (t *Table[V]) UpdatePersist(pfx netip.Prefix, cb func(val V, ok bool) V) (pt *Table[V], newVal V) { - var zero V - - if !pfx.IsValid() { - return t, zero - } - - // canonicalize prefix - pfx = pfx.Masked() - - // values derived from pfx - ip := pfx.Addr() - is4 := ip.Is4() - bits := pfx.Bits() - - pt = &Table[V]{ - root4: t.root4, - root6: t.root6, - size4: t.size4, - size6: t.size6, - } - - n := pt.rootNodeByVersion(is4) - - // clone the root of insertion path - *n = *(n.cloneFlat()) - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // find the proper trie node to update prefix - for depth, octet := range octets { - // last octet from prefix, update/insert prefix into node - if depth == lastIdx { - newVal, exists := n.prefixes.UpdateAt(pfxToIdx(octet, lastBits), cb) - if !exists { - pt.sizeUpdate(is4, 1) - } - return pt, newVal - } - - addr := uint(octet) - - // go down in tight loop to last octet - if !n.children.Test(addr) { - // insert prefix path compressed - newVal := cb(zero, false) - n.children.InsertAt(addr, &leaf[V]{pfx, newVal}) - - pt.sizeUpdate(is4, 1) - return pt, newVal - } - - // get node or leaf for octet - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - // proceed to next level - kid = kid.cloneFlat() - n.children.InsertAt(addr, kid) - n = kid - continue // descend down to next trie level - - case *leaf[V]: - kid = kid.cloneLeaf() - - // update existing value if prefixes are equal - if kid.prefix == pfx { - newVal = cb(kid.value, true) - n.children.InsertAt(addr, &leaf[V]{pfx, newVal}) - return pt, newVal - } - - // create new node - // push the leaf down - // insert new child at current leaf position (addr) - // descend down, replace n with new child - newNode := new(node[V]) - newNode.insertAtDepth(kid.prefix, kid.value, depth+1) - - n.children.InsertAt(addr, newNode) - n = newNode - - default: - panic("logic error, wrong node type") - } - } - - panic("unreachable") -} - -// Delete removes pfx from the tree, pfx does not have to be present. -func (t *Table[V]) Delete(pfx netip.Prefix) { - _, _ = t.getAndDelete(pfx) -} - -// DeletePersist is similar to Delete but the receiver isn't modified. -// All nodes touched during delete are cloned and a new Table is returned. -// -// This is orders of magnitude slower than Delete (μsec versus nsec). -func (t *Table[V]) DeletePersist(pfx netip.Prefix) *Table[V] { - pt, _, _ := t.getAndDeletePersist(pfx) - return pt -} - -// GetAndDelete deletes the prefix and returns the associated payload for prefix and true, -// or the zero value and false if prefix is not set in the routing table. -func (t *Table[V]) GetAndDelete(pfx netip.Prefix) (val V, ok bool) { - return t.getAndDelete(pfx) -} - -// GetAndDeletePersist is similar to GetAndDelete but the receiver isn't modified. -// All nodes touched during delete are cloned and a new Table is returned. -// -// If the payload V is a pointer or contains a pointer, it should -// implement the cloner interface. -// -// This is orders of magnitude slower than GetAndDelete (μsec versus nsec). -func (t *Table[V]) GetAndDeletePersist(pfx netip.Prefix) (pt *Table[V], val V, ok bool) { - return t.getAndDeletePersist(pfx) -} - -func (t *Table[V]) getAndDelete(pfx netip.Prefix) (val V, ok bool) { - if !pfx.IsValid() { - return val, false - } - - // canonicalize prefix - pfx = pfx.Masked() - - // values derived from pfx - ip := pfx.Addr() - is4 := ip.Is4() - bits := pfx.Bits() - - n := t.rootNodeByVersion(is4) - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // record path to deleted node - // needed to purge and/or path compress nodes after deletion - stack := [maxTreeDepth]*node[V]{} - - // find the trie node - for depth, octet := range octets { - // push current node on stack for path recording - stack[depth] = n - - // try to delete prefix in trie node - if depth == lastIdx { - val, ok = n.prefixes.DeleteAt(pfxToIdx(octet, lastBits)) - if !ok { - return val, false - } - - t.sizeUpdate(is4, -1) - n.purgeAndCompress(stack[:depth], octets, is4) - return val, ok - } - - addr := uint(octet) - if !n.children.Test(addr) { - return val, false - } - - // get the child: node or leaf - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue // descend down to next trie level - - case *leaf[V]: - // reached a path compressed prefix, stop traversing - if kid.prefix != pfx { - return val, false - } - - // prefix is equal leaf, delete leaf - n.children.DeleteAt(addr) - - t.sizeUpdate(is4, -1) - n.purgeAndCompress(stack[:depth], octets, is4) - - return kid.value, true - - default: - panic("logic error, wrong node type") - } - } - - panic("unreachable") -} - -// getAndDeletePersist is similar to getAndDelete but the receiver isn't modified. -func (t *Table[V]) getAndDeletePersist(pfx netip.Prefix) (pt *Table[V], val V, ok bool) { - if !pfx.IsValid() { - return t, val, false - } - - // canonicalize prefix - pfx = pfx.Masked() - - // values derived from pfx - ip := pfx.Addr() - is4 := ip.Is4() - bits := pfx.Bits() - - pt = &Table[V]{ - root4: t.root4, - root6: t.root6, - size4: t.size4, - size6: t.size6, - } - - n := pt.rootNodeByVersion(is4) - - // clone the root of insertion path - *n = *n.cloneFlat() - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // record path to deleted node - // needed to purge and/or path compress nodes after deletion - stack := [maxTreeDepth]*node[V]{} - - // find the trie node - for depth, octet := range octets { - // push cloned node on stack for path recording - stack[depth] = n - - // try to delete prefix in trie node - if depth == lastIdx { - val, ok = n.prefixes.DeleteAt(pfxToIdx(octet, lastBits)) - if !ok { - // nothing to delete - return pt, val, false - } - - pt.sizeUpdate(is4, -1) - n.purgeAndCompress(stack[:depth], octets, is4) - return pt, val, ok - } - - addr := uint(octet) - if !n.children.Test(addr) { - // nothing to delete - return pt, val, false - } - - // get the child: node or leaf - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - // proceed to next level - kid = kid.cloneFlat() - n.children.InsertAt(addr, kid) - n = kid - continue // descend down to next trie level - - case *leaf[V]: - kid = kid.cloneLeaf() - - // reached a path compressed prefix, stop traversing - if kid.prefix != pfx { - // nothing to delete - return pt, val, false - } - - // prefix is equal leaf, delete leaf - n.children.DeleteAt(addr) - - pt.sizeUpdate(is4, -1) - n.purgeAndCompress(stack[:depth], octets, is4) - - // kid.value is cloned - return pt, kid.value, true - - default: - panic("logic error, wrong node type") - } - } - - panic("unreachable") -} - -// Get returns the associated payload for prefix and true, or false if -// prefix is not set in the routing table. -func (t *Table[V]) Get(pfx netip.Prefix) (val V, ok bool) { - var zero V - - if !pfx.IsValid() { - return zero, false - } - - // canonicalize the prefix - pfx = pfx.Masked() - - // values derived from pfx - ip := pfx.Addr() - is4 := ip.Is4() - bits := pfx.Bits() - - n := t.rootNodeByVersion(is4) - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // find the trie node -LOOP: - for depth, octet := range octets { - if depth == lastIdx { - return n.prefixes.Get(pfxToIdx(octet, lastBits)) - } - - addr := uint(octet) - if !n.children.Test(addr) { - break LOOP - } - - // get the child: node or leaf - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue // descend down to next trie level - - case *leaf[V]: - // reached a path compressed prefix, stop traversing - if kid.prefix == pfx { - return kid.value, true - } - break LOOP - - default: - panic("logic error, wrong node type") - } - } - - return zero, false -} - -// Contains does a route lookup for IP and -// returns true if any route matched. -// -// Contains does not return the value nor the prefix of the matching item, -// but as a test against a black- or whitelist it's often sufficient -// and even few nanoseconds faster than [Table.Lookup]. -func (t *Table[V]) Contains(ip netip.Addr) bool { - if !ip.IsValid() { - return false - } - - is4 := ip.Is4() - n := t.rootNodeByVersion(is4) - - octets := ip.AsSlice() - - for _, octet := range octets { - addr := uint(octet) - - // contains: any lpm match good enough, no backtracking needed - if n.prefixes.Len() != 0 && n.lpmTest(hostIndex(addr)) { - return true - } - - if !n.children.Test(addr) { - return false - } - - // get node or leaf for octet - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue // descend down to next trie level - - case *leaf[V]: - return kid.prefix.Contains(ip) - - default: - panic("logic error, wrong node type") - } - } - - panic("unreachable") -} - -// Lookup does a route lookup (longest prefix match) for IP and -// returns the associated value and true, or false if no route matched. -func (t *Table[V]) Lookup(ip netip.Addr) (val V, ok bool) { - if !ip.IsValid() { - return val, false - } - - is4 := ip.Is4() - n := t.rootNodeByVersion(is4) - - octets := ip.AsSlice() - - // stack of the traversed nodes for fast backtracking, if needed - stack := [maxTreeDepth]*node[V]{} - - // run variable, used after for loop - var depth int - var octet byte - var addr uint - -LOOP: - // find leaf node - for depth, octet = range octets { - addr = uint(octet) - - // push current node on stack for fast backtracking - stack[depth] = n - - // go down in tight loop to last octet - if !n.children.Test(addr) { - // no more nodes below octet - break LOOP - } - - // get the child: node or leaf - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue // descend down to next trie level - - case *leaf[V]: - // reached a path compressed prefix, stop traversing - if kid.prefix.Contains(ip) { - return kid.value, true - } - break LOOP - - default: - panic("logic error, wrong node type") - } - } - - // start backtracking, unwind the stack, bounds check eliminated - for ; depth >= 0 && depth < len(stack) && depth < len(octets); depth-- { - n = stack[depth] - - // longest prefix match, skip if node has no prefixes - if n.prefixes.Len() != 0 { - idx := hostIndex(uint(octets[depth])) - // lpmGet(idx), manually inlined - // -------------------------------------------------------------- - if topIdx, ok := n.prefixes.IntersectionTop(lpmLookupTbl[idx]); ok { - return n.prefixes.MustGet(topIdx), true - } - // -------------------------------------------------------------- - } - } - - return val, false -} - -// LookupPrefix does a route lookup (longest prefix match) for pfx and -// returns the associated value and true, or false if no route matched. -func (t *Table[V]) LookupPrefix(pfx netip.Prefix) (val V, ok bool) { - _, val, ok = t.lookupPrefixLPM(pfx, false) - return val, ok -} - -// LookupPrefixLPM is similar to [Table.LookupPrefix], -// but it returns the lpm prefix in addition to value,ok. -// -// This method is about 20-30% slower than LookupPrefix and should only -// be used if the matching lpm entry is also required for other reasons. -// -// If LookupPrefixLPM is to be used for IP address lookups, -// they must be converted to /32 or /128 prefixes. -func (t *Table[V]) LookupPrefixLPM(pfx netip.Prefix) (lpm netip.Prefix, val V, ok bool) { - return t.lookupPrefixLPM(pfx, true) -} - -func (t *Table[V]) lookupPrefixLPM(pfx netip.Prefix, withLPM bool) (lpm netip.Prefix, val V, ok bool) { - if !pfx.IsValid() { - return lpm, val, false - } - - ip := pfx.Addr() - bits := pfx.Bits() - is4 := ip.Is4() - - n := t.rootNodeByVersion(is4) - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // mask the last octet from IP - octets[lastIdx] &= netMask(lastBits) - - // record path to leaf node - stack := [maxTreeDepth]*node[V]{} - - var depth int - var octet byte - var addr uint - -LOOP: - // find the last node on the octets path in the trie, - for depth, octet = range octets { - addr = uint(octet) - - // push current node on stack - stack[depth] = n - - // go down in tight loop to leaf node - if !n.children.Test(addr) { - break LOOP - } - - // get the child: node or leaf - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue LOOP // descend down to next trie level - - case *leaf[V]: - // reached a path compressed prefix, stop traversing - // must not be masked for Contains(pfx.Addr) - if kid.prefix.Contains(ip) && kid.prefix.Bits() <= bits { - return kid.prefix, kid.value, true - } - - break LOOP - - default: - panic("logic error, wrong node type") - } - } - - // start backtracking, unwind the stack, bounds check eliminated - for ; depth >= 0 && depth < len(stack) && depth < len(octets); depth-- { - n = stack[depth] - - // longest prefix match, skip if node has no prefixes - if n.prefixes.Len() == 0 { - continue - } - - // only the lastOctet may have a different prefix len - // all others are just host routes - var idx uint - octet = octets[depth] - if depth == lastIdx { - idx = pfxToIdx(octet, lastBits) - } else { - idx = hostIndex(uint(octet)) - } - - // manually inlined lpmGet(idx) - if topIdx, ok := n.prefixes.IntersectionTop(lpmLookupTbl[idx]); ok { - val = n.prefixes.MustGet(topIdx) - - // called from LookupPrefix - if !withLPM { - return netip.Prefix{}, val, ok - } - - // called from LookupPrefixLPM - - // calculate the pfxLen from depth and top idx - pfxLen := depth*strideLen + int(baseIdxLookupTbl[topIdx].pfxLen) - - // calculate the lpm from incoming ip and new mask - lpm, _ = ip.Prefix(pfxLen) - return lpm, val, ok - } - } - - return lpm, val, false -} - -// Supernets returns an iterator over all CIDRs covering pfx. -// The iteration is in reverse CIDR sort order, from longest-prefix-match to shortest-prefix-match. -func (t *Table[V]) Supernets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { - return func(yield func(netip.Prefix, V) bool) { - if !pfx.IsValid() { - return - } - - // canonicalize the prefix - pfx = pfx.Masked() - - // values derived from pfx - ip := pfx.Addr() - is4 := ip.Is4() - bits := pfx.Bits() - - n := t.rootNodeByVersion(is4) - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // stack of the traversed nodes for reverse ordering of supernets - stack := [maxTreeDepth]*node[V]{} - - // run variable, used after for loop - var depth int - var octet byte - - // find last node along this octet path - LOOP: - for depth, octet = range octets { - addr := uint(octet) - - // push current node on stack - stack[depth] = n - - if !n.children.Test(addr) { - break LOOP - } - - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue LOOP // descend down to next trie level - - case *leaf[V]: - if kid.prefix.Overlaps(pfx) && kid.prefix.Bits() <= pfx.Bits() { - if !yield(kid.prefix, kid.value) { - // early exit - return - } - } - // end of trie along this octets path - break LOOP - - default: - panic("logic error, wrong node type") - } - } - - // start backtracking, unwind the stack - for ; depth >= 0; depth-- { - n = stack[depth] - - // micro benchmarking - if n.prefixes.Len() == 0 { - continue - } - - // only the lastOctet may have a different prefix len - // all others are just host routes - pfxLen := strideLen - if depth == lastIdx { - pfxLen = lastBits - } - - if !n.eachLookupPrefix(octets, depth, is4, pfxLen, yield) { - // early exit - return - } - } - } -} - -// Subnets returns an iterator over all CIDRs covered by pfx. -// The iteration is in natural CIDR sort order. -func (t *Table[V]) Subnets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V] { - return func(yield func(netip.Prefix, V) bool) { - if !pfx.IsValid() { - return - } - - // canonicalize the prefix - pfx = pfx.Masked() - - // values derived from pfx - ip := pfx.Addr() - is4 := ip.Is4() - bits := pfx.Bits() - - n := t.rootNodeByVersion(is4) - - lastIdx, lastBits := lastOctetIdxAndBits(bits) - - octets := ip.AsSlice() - octets = octets[:lastIdx+1] - - // find the trie node - for depth, octet := range octets { - if depth == lastIdx { - _ = n.eachSubnet(octets, depth, is4, lastBits, yield) - return - } - - addr := uint(octet) - if !n.children.Test(addr) { - return - } - - // node or leaf? - switch kid := n.children.MustGet(addr).(type) { - case *node[V]: - n = kid - continue // descend down to next trie level - - case *leaf[V]: - if pfx.Overlaps(kid.prefix) && pfx.Bits() <= kid.prefix.Bits() { - _ = yield(kid.prefix, kid.value) - } - return - - default: - panic("logic error, wrong node type") - } - } - } -} - -// OverlapsPrefix reports whether any IP in pfx is matched by a route in the table or vice versa. -func (t *Table[V]) OverlapsPrefix(pfx netip.Prefix) bool { - if !pfx.IsValid() { - return false - } - - // canonicalize the prefix - pfx = pfx.Masked() - - is4 := pfx.Addr().Is4() - n := t.rootNodeByVersion(is4) - - return n.overlapsPrefixAtDepth(pfx, 0) -} - -// Overlaps reports whether any IP in the table is matched by a route in the -// other table or vice versa. -func (t *Table[V]) Overlaps(o *Table[V]) bool { - return t.Overlaps4(o) || t.Overlaps6(o) -} - -// Overlaps4 reports whether any IPv4 in the table matches a route in the -// other table or vice versa. -func (t *Table[V]) Overlaps4(o *Table[V]) bool { - if t.size4 == 0 || o.size4 == 0 { - return false - } - return t.root4.overlaps(&o.root4, 0) -} - -// Overlaps6 reports whether any IPv6 in the table matches a route in the -// other table or vice versa. -func (t *Table[V]) Overlaps6(o *Table[V]) bool { - if t.size6 == 0 || o.size6 == 0 { - return false - } - return t.root6.overlaps(&o.root6, 0) -} - -// Union combines two tables, changing the receiver table. -// If there are duplicate entries, the payload of type V is shallow copied from the other table. -// If type V implements the [Cloner] interface, the values are cloned, see also [Table.Clone]. -func (t *Table[V]) Union(o *Table[V]) { - dup4 := t.root4.unionRec(&o.root4, 0) - dup6 := t.root6.unionRec(&o.root6, 0) - - t.size4 += o.size4 - dup4 - t.size6 += o.size6 - dup6 -} - -// Cloner, if implemented by payload of type V the values are deeply copied -// during [Table.UpdatePersist], [Table.DeletePersist], [Table.Clone] and [Table.Union]. -type Cloner[V any] interface { - Clone() V -} - -// Clone returns a copy of the routing table. -// The payload of type V is shallow copied, but if type V implements the [Cloner] interface, -// the values are cloned. -func (t *Table[V]) Clone() *Table[V] { - if t == nil { - return nil - } - - c := new(Table[V]) - - c.root4 = *t.root4.cloneRec() - c.root6 = *t.root6.cloneRec() - - c.size4 = t.size4 - c.size6 = t.size6 - - return c -} - -func (t *Table[V]) sizeUpdate(is4 bool, n int) { - if is4 { - t.size4 += n - return - } - t.size6 += n -} - -// Size returns the prefix count. -func (t *Table[V]) Size() int { - return t.size4 + t.size6 -} - -// Size4 returns the IPv4 prefix count. -func (t *Table[V]) Size4() int { - return t.size4 -} - -// Size6 returns the IPv6 prefix count. -func (t *Table[V]) Size6() int { - return t.size6 -} - -// All returns an iterator over key-value pairs from Table. The iteration order -// is not specified and is not guaranteed to be the same from one call to the -// next. -func (t *Table[V]) All() iter.Seq2[netip.Prefix, V] { - return func(yield func(netip.Prefix, V) bool) { - _ = t.root4.allRec(stridePath{}, 0, true, yield) && t.root6.allRec(stridePath{}, 0, false, yield) - } -} - -// All4, like [Table.All] but only for the v4 routing table. -func (t *Table[V]) All4() iter.Seq2[netip.Prefix, V] { - return func(yield func(netip.Prefix, V) bool) { - _ = t.root4.allRec(stridePath{}, 0, true, yield) - } -} - -// All6, like [Table.All] but only for the v6 routing table. -func (t *Table[V]) All6() iter.Seq2[netip.Prefix, V] { - return func(yield func(netip.Prefix, V) bool) { - _ = t.root6.allRec(stridePath{}, 0, false, yield) - } -} - -// AllSorted returns an iterator over key-value pairs from Table2 in natural CIDR sort order. -func (t *Table[V]) AllSorted() iter.Seq2[netip.Prefix, V] { - return func(yield func(netip.Prefix, V) bool) { - _ = t.root4.allRecSorted(stridePath{}, 0, true, yield) && - t.root6.allRecSorted(stridePath{}, 0, false, yield) - } -} - -// AllSorted4, like [Table.AllSorted] but only for the v4 routing table. -func (t *Table[V]) AllSorted4() iter.Seq2[netip.Prefix, V] { - return func(yield func(netip.Prefix, V) bool) { - _ = t.root4.allRecSorted(stridePath{}, 0, true, yield) - } -} - -// AllSorted6, like [Table.AllSorted] but only for the v6 routing table. -func (t *Table[V]) AllSorted6() iter.Seq2[netip.Prefix, V] { - return func(yield func(netip.Prefix, V) bool) { - _ = t.root6.allRecSorted(stridePath{}, 0, false, yield) - } -} - -// lastOctetIdxAndBits, get last significant octet Idx and significant bits -// -// lastIdx: -// -// 10.0.0.0/8 -> 0 -// 10.12.0.0/15 -> 1 -// 10.12.0.0/16 -> 1 -// 10.12.10.9/32 -> 3 -// -// lastBits: -// -// 10.0.0.0/8 -> 8 -// 10.12.0.0/15 -> 7 -// 10.12.0.0/16 -> 8 -// 10.12.10.9/32 -> 8 -// -// lastOctet := octets[lastIdx] -// -// 10.0.0.0/8 -> 10 -// 10.12.0.0/15 -> 12 -// 10.12.0.0/16 -> 12 -// 10.12.10.9/32 -> 9 -func lastOctetIdxAndBits(bits int) (lastIdx, lastBits int) { - if bits == 0 { - return - } - - lastIdx = (bits - 1) >> 3 - lastBits = bits - (lastIdx << 3) - - return -} - -// noCopy may be added to structs which must not be copied -// after the first use. -// -// type My struct { -// _ noCopy -// A state -// b foo -// } -// -// See https://golang.org/issues/8005#issuecomment-190753527 -// for details. -// -// Note that it must not be embedded, due to the Lock and Unlock methods. -type noCopy struct{} - -// Lock is a no-op used by -copylocks checker from `go vet`. -func (*noCopy) Lock() {} -func (*noCopy) Unlock() {} diff --git a/vendor/github.com/go-json-experiment/json/README.md b/vendor/github.com/go-json-experiment/json/README.md index 937c398..557deb8 100644 --- a/vendor/github.com/go-json-experiment/json/README.md +++ b/vendor/github.com/go-json-experiment/json/README.md @@ -1,85 +1,20 @@ # JSON Serialization (v2) [![GoDev](https://img.shields.io/static/v1?label=godev&message=reference&color=00add8)](https://pkg.go.dev/github.com/go-json-experiment/json) -[![Build Status](https://github.com/go-json-experiment/json/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/go-json-experiment/json/actions) +[![Build Status](https://github.com/go-json-experiment/json/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/go-json-experiment/json/actions) -This module hosts an experimental implementation of v2 `encoding/json`. -The API is unstable and breaking changes will regularly be made. -Do not depend on this in publicly available modules. +This module currently hosts a mirror of `encoding/json/v2`. +Importing this package with the `goexperiment.jsonv2` build tag +(which is enabled by default on Go 1.27) will alias the implementation +in the Go standard library. -Any commits that make breaking API or behavior changes will be marked -with the string "WARNING: " near the top of the commit message. -It is your responsibility to inspect the list of commit changes -when upgrading the module. Not all breaking changes will lead to build failures. - -A [proposal to include this module in Go as `encoding/json/v2` and `encoding/json/jsontext`](https://github.com/golang/go/issues/71497) has been started on the Go Github project on 2025-01-30. Please provide your feedback there. - -## Goals and objectives - -* **Mostly backwards compatible:** If possible, v2 should aim to be _mostly_ -compatible with v1 in terms of both API and default behavior to ease migration. -For example, the `Marshal` and `Unmarshal` functions are the most widely used -declarations in the v1 package. It seems sensible for equivalent functionality -in v2 to be named the same and have a mostly compatible signature. -Behaviorally, we should aim for 95% to 99% backwards compatibility. -We do not aim for 100% compatibility since we want the freedom to break -certain behaviors that are now considered to have been a mistake. -Options exist that can bring the v2 implementation to 100% compatibility, -but it will not be the default. - -* **More flexible:** There is a -[long list of feature requests](https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+encoding%2Fjson+in%3Atitle). -We should aim to provide the most flexible features that addresses most usages. -We do not want to over fit the v2 API to handle every possible use case. -Ideally, the features provided should be orthogonal in nature such that -any combination of features results in as few surprising edge cases as possible. - -* **More performant:** JSON serialization is widely used and any bit of extra -performance gains will be greatly appreciated. Some rarely used behaviors of v1 -may be dropped in favor of better performance. For example, -despite `Encoder` and `Decoder` operating on an `io.Writer` and `io.Reader`, -they do not operate in a truly streaming manner, -leading to a loss in performance. The v2 implementation should aim to be truly -streaming by default (see [#33714](https://golang.org/issue/33714)). - -* **Easy to use (hard to misuse):** The v2 API should aim to make -the common case easy and the less common case at least possible. -The API should avoid behavior that goes contrary to user expectation, -which may result in subtle bugs (see [#36225](https://golang.org/issue/36225)). - -* **v1 and v2 maintainability:** Since the v1 implementation must stay forever, -it would be beneficial if v1 could be implemented under the hood with v2, -allowing for less maintenance burden in the future. This probably implies that -behavioral changes in v2 relative to v1 need to be exposed as options. - -* **Avoid unsafe:** Standard library packages generally avoid the use of -package `unsafe` even if it could provide a performance boost. -We aim to preserve this property. - -## Expectations - -While this module aims to possibly be the v2 implementation of `encoding/json`, -there is no guarantee that this outcome will occur. As with any major change -to the Go standard library, this will eventually go through the -[Go proposal process](https://github.com/golang/proposal#readme). -At the present moment, this is still in the design and experimentation phase -and is not ready for a formal proposal. - -There are several possible outcomes from this experiment: -1. We determine that a v2 `encoding/json` would not provide sufficient benefit -over the existing v1 `encoding/json` package. Thus, we abandon this effort. -2. We propose a v2 `encoding/json` design, but it is rejected in favor of some -other design that is considered superior. -3. We propose a v2 `encoding/json` design, but rather than adding an entirely -new v2 `encoding/json` package, we decide to merge its functionality into -the existing v1 `encoding/json` package. -4. We propose a v2 `encoding/json` design and it is accepted, resulting in -its addition to the standard library. -5. Some other unforeseen outcome (among the infinite number of possibilities). +This module contained the historical prototype of `encoding/json/v2` +before it was formally adopted into the Go standard library +as an experiment in Go 1.25 and then later as a stable API in Go 1.27. ## Development -This module is primarily developed by +This module was primarily developed by [@dsnet](https://github.com/dsnet), [@mvdan](https://github.com/mvdan), and [@johanbrandhorst](https://github.com/johanbrandhorst) @@ -87,6 +22,11 @@ with feedback provided by [@rogpeppe](https://github.com/rogpeppe), [@ChrisHines](https://github.com/ChrisHines), and [@rsc](https://github.com/rsc). +During the process to adopt the project into the Go standard library, +API review was provided by +[@aclements](https://github.com/aclements), +[@neild](https://github.com/neild), and +[@prattmic](https://github.com/prattmic). Discussion about semantics occur semi-regularly, where a [record of past meetings can be found here](https://docs.google.com/document/d/1rovrOTd-wTawGMPPlPuKhwXaYBg9VszTXR9AQQL5LfI/edit?usp=sharing). @@ -130,40 +70,6 @@ while others affect it at the semantic layer. Some options only affect JSON when decoding, while others affect JSON while encoding. -## Behavior changes - -The v2 `json` package changes the default behavior of `Marshal` and `Unmarshal` -relative to the v1 `json` package to be more sensible. -Some of these behavior changes have options and workarounds to opt into -behavior similar to what v1 provided. - -This table shows an overview of the changes: - -| v1 | v2 | Details | -| -- | -- | ------- | -| JSON object members are unmarshaled into a Go struct using a **case-insensitive name match**. | JSON object members are unmarshaled into a Go struct using a **case-sensitive name match**. | [CaseSensitivity](/v1/diff_test.go#:~:text=TestCaseSensitivity) | -| When marshaling a Go struct, a struct field marked as `omitempty` is omitted if **the field value is an empty Go value**, which is defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string. | When marshaling a Go struct, a struct field marked as `omitempty` is omitted if **the field value would encode as an empty JSON value**, which is defined as a JSON null, or an empty JSON string, object, or array. | [OmitEmptyOption](/v1/diff_test.go#:~:text=TestOmitEmptyOption) | -| The `string` option **does affect** Go strings and bools. | The `string` option **does not affect** Go strings or bools. | [StringOption](/v1/diff_test.go#:~:text=TestStringOption) | -| The `string` option **does not recursively affect** sub-values of the Go field value. | The `string` option **does recursively affect** sub-values of the Go field value. | [StringOption](/v1/diff_test.go#:~:text=TestStringOption) | -| The `string` option **sometimes accepts** a JSON null escaped within a JSON string. | The `string` option **never accepts** a JSON null escaped within a JSON string. | [StringOption](/v1/diff_test.go#:~:text=TestStringOption) | -| A nil Go slice is marshaled as a **JSON null**. | A nil Go slice is marshaled as an **empty JSON array**. | [NilSlicesAndMaps](/v1/diff_test.go#:~:text=TestNilSlicesAndMaps) | -| A nil Go map is marshaled as a **JSON null**. | A nil Go map is marshaled as an **empty JSON object**. | [NilSlicesAndMaps](/v1/diff_test.go#:~:text=TestNilSlicesAndMaps) | -| A Go array may be unmarshaled from a **JSON array of any length**. | A Go array must be unmarshaled from a **JSON array of the same length**. | [Arrays](/v1/diff_test.go#:~:text=Arrays) | -| A Go byte array is represented as a **JSON array of JSON numbers**. | A Go byte array is represented as a **Base64-encoded JSON string**. | [ByteArrays](/v1/diff_test.go#:~:text=TestByteArrays) | -| `MarshalJSON` and `UnmarshalJSON` methods declared on a pointer receiver are **inconsistently called**. | `MarshalJSON` and `UnmarshalJSON` methods declared on a pointer receiver are **consistently called**. | [PointerReceiver](/v1/diff_test.go#:~:text=TestPointerReceiver) | -| A Go map is marshaled in a **deterministic order**. | A Go map is marshaled in a **non-deterministic order**. | [MapDeterminism](/v1/diff_test.go#:~:text=TestMapDeterminism) | -| JSON strings are encoded **with HTML-specific characters being escaped**. | JSON strings are encoded **without any characters being escaped** (unless necessary). | [EscapeHTML](/v1/diff_test.go#:~:text=TestEscapeHTML) | -| When marshaling, invalid UTF-8 within a Go string **are silently replaced**. | When marshaling, invalid UTF-8 within a Go string **results in an error**. | [InvalidUTF8](/v1/diff_test.go#:~:text=TestInvalidUTF8) | -| When unmarshaling, invalid UTF-8 within a JSON string **are silently replaced**. | When unmarshaling, invalid UTF-8 within a JSON string **results in an error**. | [InvalidUTF8](/v1/diff_test.go#:~:text=TestInvalidUTF8) | -| When marshaling, **an error does not occur** if the output JSON value contains objects with duplicate names. | When marshaling, **an error does occur** if the output JSON value contains objects with duplicate names. | [DuplicateNames](/v1/diff_test.go#:~:text=TestDuplicateNames) | -| When unmarshaling, **an error does not occur** if the input JSON value contains objects with duplicate names. | When unmarshaling, **an error does occur** if the input JSON value contains objects with duplicate names. | [DuplicateNames](/v1/diff_test.go#:~:text=TestDuplicateNames) | -| Unmarshaling a JSON null into a non-empty Go value **inconsistently clears the value or does nothing**. | Unmarshaling a JSON null into a non-empty Go value **always clears the value**. | [MergeNull](/v1/diff_test.go#:~:text=TestMergeNull) | -| Unmarshaling a JSON value into a non-empty Go value **follows inconsistent and bizarre behavior**. | Unmarshaling a JSON value into a non-empty Go value **always merges if the input is an object, and otherwise replaces**. | [MergeComposite](/v1/diff_test.go#:~:text=TestMergeComposite) | -| A `time.Duration` is represented as a **JSON number containing the decimal number of nanoseconds**. | A `time.Duration` has no default representation in v2 (see [#71631](https://golang.org/issue/71631)) and results in an error. | | -| A Go struct with only unexported fields **can be serialized**. | A Go struct with only unexported fields **cannot be serialized**. | [EmptyStructs](/v1/diff_test.go#:~:text=TestEmptyStructs) | - -See [diff_test.go](/v1/diff_test.go) for details about every change. - ## Performance One of the goals of the v2 module is to be more performant than v1, diff --git a/vendor/github.com/go-json-experiment/json/alias.go b/vendor/github.com/go-json-experiment/json/alias.go index ebbdffb..04a68f7 100644 --- a/vendor/github.com/go-json-experiment/json/alias.go +++ b/vendor/github.com/go-json-experiment/json/alias.go @@ -11,6 +11,8 @@ // primitive data types such as booleans, strings, and numbers, // in addition to structured data types such as objects and arrays. // +// See the [Working with JSON] tutorial for an introduction to this package. +// // [Marshal] and [Unmarshal] encode and decode Go values // to/from JSON text contained within a []byte. // [MarshalWrite] and [UnmarshalRead] operate on JSON text @@ -55,7 +57,7 @@ // if [RejectUnknownMembers] is specified. // // The representation of each struct field can be customized in the -// "json" struct field tag, where the tag is a comma separated list of options. +// "json" struct field tag, where the tag is a comma-separated list of options. // As a special case, if the entire tag is `json:"-"`, // then the field is ignored with regard to its JSON representation. // Some options also have equivalent behavior controlled by a caller-specified [Options]. @@ -63,11 +65,7 @@ // // The first option is the JSON object name override for the Go struct field. // If the name is not specified, then the Go struct field name -// is used as the JSON object name. JSON names containing commas or quotes, -// or names identical to "" or "-", can be specified using -// a single-quoted string literal, where the syntax is identical to -// the Go grammar for a double-quoted string literal, -// but instead uses single quotes as the delimiters. +// is used as the JSON object name. // By default, unmarshaling uses case-sensitive matching to identify // the Go struct field associated with a JSON object name. // @@ -84,60 +82,49 @@ // encoded as a JSON null, empty string, empty object, or empty array. // This option has no effect when unmarshaling. // -// - string: The "string" option specifies that [StringifyNumbers] -// be set when marshaling or unmarshaling a struct field value. -// This causes numeric types to be encoded as a JSON number -// within a JSON string, and to be decoded from a JSON string -// containing the JSON number without any surrounding whitespace. -// This extra level of encoding is often necessary since -// many JSON parsers cannot precisely represent 64-bit integers. +// - string: The "string" option specifies that [StringifyNumbers] be set +// when marshaling or unmarshaling a struct field value. +// This causes types that would normally be encoded as a JSON number +// to instead be encoded as a JSON number quoted within a JSON string, +// and to be decoded from a JSON string containing the JSON number +// without any surrounding whitespace. +// The "string" option only applies to the top-level of the Go struct field +// value. It is an error to apply this option to any type that does not +// encode as a JSON number. +// Note that composite types such as arrays, slices, structs, and maps do +// not encode as a JSON number, so applying this option will cause an error +// rather than affecting JSON numbers within such types. +// This extra level of encoding is often necessary since many JSON parsers +// cannot precisely represent 64-bit integers. // // - case: When unmarshaling, the "case" option specifies how // JSON object names are matched with the JSON name for Go struct fields. // The option is a key-value pair specified as "case:value" where // the value must either be 'ignore' or 'strict'. -// The 'ignore' value specifies that matching is case-insensitive -// where dashes and underscores are also ignored. If multiple fields match, -// the first declared field in breadth-first order takes precedence. +// The 'ignore' value specifies that matching is case-insensitive, +// and also ignores dashes and underscores. If multiple fields match, +// then the field with an exact name match is selected, otherwise an error +// is reported because the choice of field to unmarshal into is ambiguous. // The 'strict' value specifies that matching is case-sensitive. // This takes precedence over the [MatchCaseInsensitiveNames] option. // -// - inline: The "inline" option specifies that +// - embed: The "embed" option specifies that // the JSON representable content of this field type is to be promoted -// as if they were specified in the parent struct. +// as if it were specified in the parent struct. // It is the JSON equivalent of Go struct embedding. -// A Go embedded field is implicitly inlined unless an explicit JSON name -// is specified. The inlined field must be a Go struct +// A Go embedded field is implicitly JSON embedded unless +// an explicit JSON name is specified. The embedded field must be a Go struct // (that does not implement any JSON methods), [jsontext.Value], // map[~string]T, or an unnamed pointer to such types. When marshaling, -// inlined fields from a pointer type are omitted if it is nil. -// Inlined fields of type [jsontext.Value] and map[~string]T are called -// “inlined fallbacks” as they can represent all possible +// embedded fields from a pointer type are omitted if it is nil. +// Embedded fields of type [jsontext.Value] and map[~string]T are called +// “embedded fallbacks” as they can represent all possible // JSON object members not directly handled by the parent struct. -// Only one inlined fallback field may be specified in a struct, +// Only one embedded fallback field may be specified in a struct, // while many non-fallback fields may be specified. This option // must not be specified with any other option (including the JSON name). // -// - unknown: The "unknown" option is a specialized variant -// of the inlined fallback to indicate that this Go struct field -// contains any number of unknown JSON object members. The field type must -// be a [jsontext.Value], map[~string]T, or an unnamed pointer to such types. -// If [DiscardUnknownMembers] is specified when marshaling, -// the contents of this field are ignored. -// If [RejectUnknownMembers] is specified when unmarshaling, -// any unknown object members are rejected regardless of whether -// an inlined fallback with the "unknown" option exists. This option -// must not be specified with any other option (including the JSON name). -// -// - format: The "format" option specifies a format flag -// used to specialize the formatting of the field value. -// The option is a key-value pair specified as "format:value" where -// the value must be either a literal consisting of letters and numbers -// (e.g., "format:RFC3339") or a single-quoted string literal -// (e.g., "format:'2006-01-02'"). The interpretation of the format flag -// is determined by the struct field type. -// -// The "omitzero" and "omitempty" options are mostly semantically identical. +// The "omitzero" and "omitempty" options behave similarly. // The former is defined in terms of the Go type system, // while the latter in terms of the JSON type system. // Consequently they behave differently in some circumstances. @@ -146,14 +133,14 @@ // The "omitzero" option is useful for types with a well-defined zero value // (e.g., [net/netip.Addr]) or have an IsZero method (e.g., [time.Time.IsZero]). // -// Every Go struct corresponds to a list of JSON representable fields +// Every Go struct corresponds to a list of JSON-representable fields // which is constructed by performing a breadth-first search over // all struct fields (excluding unexported or ignored fields), -// where the search recursively descends into inlined structs. -// The set of non-inlined fields in a struct must have unique JSON names. +// where the search recursively descends into embedded structs. +// The set of non-embedded fields in a struct must have unique JSON names. // If multiple fields all have the same JSON name, then the one // at shallowest depth takes precedence and the other fields at deeper depths -// are excluded from the list of JSON representable fields. +// are excluded from the list of JSON-representable fields. // If multiple fields at the shallowest depth have the same JSON name, // but exactly one is explicitly tagged with a JSON name, // then that field takes precedence and all others are excluded from the list. @@ -161,7 +148,7 @@ // with embedded struct types. // // Marshaling or unmarshaling a non-empty struct -// without any JSON representable fields results in a [SemanticError]. +// without any JSON-representable fields results in a [SemanticError]. // Unexported fields must not have any `json` tags except for `json:"-"`. // // # Security Considerations @@ -173,8 +160,8 @@ // // [For example, suppose we have two micro-services.] // The first service is responsible for authenticating a JSON request, -// while the second service is responsible for executing the request -// (having assumed that the prior service authenticated the request). +// while the second service is responsible for executing the request, +// assuming that it was authenticated. // If an attacker were able to maliciously craft a JSON request such that // both services believe that the same request is from different users, // it could bypass the authenticator with valid credentials for one user, @@ -256,6 +243,7 @@ // The v2 API generally chooses more secure defaults than v1, // but care should still be taken with large integers or unknown members. // +// [Working with JSON]: https://go.dev/doc/tutorial/json // [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057s package json @@ -274,19 +262,21 @@ import ( // Functions or methods that operate on *T are only called when encoding // a value of type T (by taking its address) or a non-nil value of *T. // Marshal ensures that a value is always addressable -// (by boxing it on the heap if necessary) so that +// (by copying the value if necessary) so that // these functions and methods can be consistently called. For performance, // it is recommended that Marshal be passed a non-nil pointer to the value. // -// The input value is encoded as JSON according the following rules: +// The input value is encoded as JSON according to the following rules: // // - If any type-specific functions in a [WithMarshalers] option match // the value type, then those functions are called to encode the value. -// If all applicable functions return [SkipFunc], +// If all applicable functions return [errors.ErrUnsupported], // then the value is encoded according to subsequent rules. // // - If the value type implements [MarshalerTo], // then the MarshalJSONTo method is called to encode the value. +// If the method returns [errors.ErrUnsupported], +// then the input is encoded according to subsequent rules. // // - If the value type implements [Marshaler], // then the MarshalJSON method is called to encode the value. @@ -302,51 +292,31 @@ import ( // - Otherwise, the value is encoded according to the value's type // as described in detail below. // -// Most Go types have a default JSON representation. -// Certain types support specialized formatting according to -// a format flag optionally specified in the Go struct tag -// for the struct field that contains the current value -// (see the “JSON Representation of Go structs” section for more details). -// -// The representation of each type is as follows: +// Most Go types have a default JSON representation as follows: // // - A Go boolean is encoded as a JSON boolean (e.g., true or false). -// It does not support any custom format flags. // // - A Go string is encoded as a JSON string. -// It does not support any custom format flags. // // - A Go []byte or [N]byte is encoded as a JSON string containing -// the binary value encoded using RFC 4648. -// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. -// If the format is "base64url", then this uses RFC 4648, section 5. -// If the format is "base32", then this uses RFC 4648, section 6. -// If the format is "base32hex", then this uses RFC 4648, section 7. -// If the format is "base16" or "hex", then this uses RFC 4648, section 8. -// If the format is "array", then the bytes value is encoded as a JSON array -// where each byte is recursively JSON-encoded as each JSON array element. +// a binary value using Base 64 Encoding per RFC 4648, section 4. // // - A Go integer is encoded as a JSON number without fractions or exponents. // If [StringifyNumbers] is specified or encoding a JSON object name, // then the JSON number is encoded within a JSON string. -// It does not support any custom format flags. // // - A Go float is encoded as a JSON number. // If [StringifyNumbers] is specified or encoding a JSON object name, // then the JSON number is encoded within a JSON string. -// If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded as -// the JSON strings "NaN", "Infinity", and "-Infinity", respectively. -// Otherwise, the presence of non-finite numbers results in a [SemanticError]. +// Encoding a NaN or ±Inf results in a [SemanticError]. // // - A Go map is encoded as a JSON object, where each Go map key and value // is recursively encoded as a name and value pair in the JSON object. // The Go map key must encode as a JSON string, otherwise this results // in a [SemanticError]. The Go map is traversed in a non-deterministic order. // For deterministic encoding, consider using the [Deterministic] option. -// If the format is "emitnull", then a nil map is encoded as a JSON null. -// If the format is "emitempty", then a nil map is encoded as an empty JSON object, -// regardless of whether [FormatNilMapAsNull] is specified. -// Otherwise by default, a nil map is encoded as an empty JSON object. +// By default, a nil map is encoded as an empty JSON object, +// unless the [FormatNilMapAsNull] option is specified. // // - A Go struct is encoded as a JSON object. // See the “JSON Representation of Go structs” section @@ -354,53 +324,33 @@ import ( // // - A Go slice is encoded as a JSON array, where each Go slice element // is recursively JSON-encoded as the elements of the JSON array. -// If the format is "emitnull", then a nil slice is encoded as a JSON null. -// If the format is "emitempty", then a nil slice is encoded as an empty JSON array, -// regardless of whether [FormatNilSliceAsNull] is specified. -// Otherwise by default, a nil slice is encoded as an empty JSON array. +// By default, a nil slice is encoded as an empty JSON array, +// unless the [FormatNilSliceAsNull] option is specified. // // - A Go array is encoded as a JSON array, where each Go array element // is recursively JSON-encoded as the elements of the JSON array. // The JSON array length is always identical to the Go array length. -// It does not support any custom format flags. // // - A Go pointer is encoded as a JSON null if nil, otherwise it is // the recursively JSON-encoded representation of the underlying value. -// Format flags are forwarded to the encoding of the underlying value. // // - A Go interface is encoded as a JSON null if nil, otherwise it is // the recursively JSON-encoded representation of the underlying value. -// It does not support any custom format flags. // // - A Go [time.Time] is encoded as a JSON string containing the timestamp // formatted in RFC 3339 with nanosecond precision. -// If the format matches one of the format constants declared -// in the time package (e.g., RFC1123), then that format is used. -// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", -// then the timestamp is encoded as a possibly fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds) -// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. -// To avoid a fractional component, round the timestamp to the relevant unit. -// Otherwise, the format is used as-is with [time.Time.Format] if non-empty. // // - A Go [time.Duration] currently has no default representation and -// requires an explicit format to be specified. -// If the format is "sec", "milli", "micro", or "nano", -// then the duration is encoded as a possibly fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds). -// To avoid a fractional component, round the duration to the relevant unit. -// If the format is "units", it is encoded as a JSON string formatted using -// [time.Duration.String] (e.g., "1h30m" for 1 hour 30 minutes). -// If the format is "iso8601", it is encoded as a JSON string using the -// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) -// using only accurate units of hours, minutes, and seconds. +// results in a [SemanticError], unless the [encoding/json.FormatDurationAsNano] +// option is specified, in which case it is encoded as a JSON number +// without fractions or exponents, representing the duration in nanoseconds. // // - All other Go types (e.g., complex numbers, channels, and functions) // have no default representation and result in a [SemanticError]. // // JSON cannot represent cyclic data structures and Marshal does not handle them. -// Passing cyclic structures will result in an error. func Marshal(in any, opts ...Options) (out []byte, err error) { + opts = mayAppendSupportFormatTag(opts) return json.Marshal(in, opts...) } @@ -409,18 +359,18 @@ func Marshal(in any, opts ...Options) (out []byte, err error) { // It does not terminate the output with a newline. // See [Marshal] for details about the conversion of a Go value into JSON. func MarshalWrite(out io.Writer, in any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) return json.MarshalWrite(out, in, opts...) } // MarshalEncode serializes a Go value into an [jsontext.Encoder] according to -// the provided marshal options (while ignoring unmarshal, encode, or decode options). -// Any marshal-relevant options already specified on the [jsontext.Encoder] -// take lower precedence than the set of options provided by the caller. -// Unlike [Marshal] and [MarshalWrite], encode options are ignored because -// they must have already been specified on the provided [jsontext.Encoder]. +// the provided marshal or encode options (while ignoring unmarshal or decode options). +// The options provided take precedence over options already applied on +// the [jsontext.Encoder] and only apply for the duration of the marshal call. // // See [Marshal] for details about the conversion of a Go value into JSON. func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) return json.MarshalEncode(out, in, opts...) } @@ -434,18 +384,24 @@ func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { // Functions or methods that operate on *T are only called when decoding // a value of type T (by taking its address) or a non-nil value of *T. // Unmarshal ensures that a value is always addressable -// (by boxing it on the heap if necessary) so that +// (by copying the value if necessary) so that // these functions and methods can be consistently called. +// If a value must be shallow copied to call a pointer-receiver +// [Unmarshaler], [UnmarshalerFrom], or [encoding.TextUnmarshaler] method, +// then any mutations performed by the method are shallow copied back +// into the destination value. // -// The input is decoded into the output according the following rules: +// The input is decoded into the output according to the following rules: // // - If any type-specific functions in a [WithUnmarshalers] option match // the value type, then those functions are called to decode the JSON -// value. If all applicable functions return [SkipFunc], +// value. If all applicable functions return [errors.ErrUnsupported], // then the input is decoded according to subsequent rules. // // - If the value type implements [UnmarshalerFrom], // then the UnmarshalJSONFrom method is called to decode the JSON value. +// If the method returns [errors.ErrUnsupported], +// then the input is decoded according to subsequent rules. // // - If the value type implements [Unmarshaler], // then the UnmarshalJSON method is called to decode the JSON value. @@ -459,10 +415,6 @@ func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { // as described in detail below. // // Most Go types have a default JSON representation. -// Certain types support specialized formatting according to -// a format flag optionally specified in the Go struct tag -// for the struct field that contains the current value -// (see the “JSON Representation of Go structs” section for more details). // A JSON null may be decoded into every supported Go value where // it is equivalent to storing the zero value of the Go value. // If the input JSON kind is not handled by the current Go value type, @@ -472,20 +424,11 @@ func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { // The representation of each type is as follows: // // - A Go boolean is decoded from a JSON boolean (e.g., true or false). -// It does not support any custom format flags. // // - A Go string is decoded from a JSON string. -// It does not support any custom format flags. // -// - A Go []byte or [N]byte is decoded from a JSON string -// containing the binary value encoded using RFC 4648. -// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. -// If the format is "base64url", then this uses RFC 4648, section 5. -// If the format is "base32", then this uses RFC 4648, section 6. -// If the format is "base32hex", then this uses RFC 4648, section 7. -// If the format is "base16" or "hex", then this uses RFC 4648, section 8. -// If the format is "array", then the Go slice or array is decoded from a -// JSON array where each JSON element is recursively decoded for each byte. +// - A Go []byte or [N]byte is decoded from a JSON string containing +// a binary value using Base 64 Encoding per RFC 4648, section 4. // When decoding into a non-nil []byte, the slice length is reset to zero // and the decoded input is appended to it. // When decoding into a [N]byte, the input must decode to exactly N bytes, @@ -497,15 +440,13 @@ func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { // It fails with a [SemanticError] if the JSON number // has a fractional or exponent component. // It also fails if it overflows the representation of the Go integer type. -// It does not support any custom format flags. // // - A Go float is decoded from a JSON number. // It must be decoded from a JSON string containing a JSON number // if [StringifyNumbers] is specified or decoding a JSON object name. // It fails if it overflows the representation of the Go float type. -// If the format is "nonfinite", then the JSON strings -// "NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf. -// Otherwise, the presence of such strings results in a [SemanticError]. +// Since JSON lacks a native representation for a NaN or ±Inf, +// such values cannot be the result of decoding. // // - A Go map is decoded from a JSON object, // where each JSON object name and value pair is recursively decoded @@ -513,7 +454,6 @@ func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { // If the Go map is nil, then a new map is allocated to decode into. // If the decoded key matches an existing Go map entry, the entry value // is reused by decoding the JSON object value into it. -// The formats "emitnull" and "emitempty" have no effect when decoding. // // - A Go struct is decoded from a JSON object. // See the “JSON Representation of Go structs” section @@ -523,20 +463,17 @@ func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { // is recursively decoded and appended to the Go slice. // Before appending into a Go slice, a new slice is allocated if it is nil, // otherwise the slice length is reset to zero. -// The formats "emitnull" and "emitempty" have no effect when decoding. // // - A Go array is decoded from a JSON array, where each JSON array element // is recursively decoded as each corresponding Go array element. // Each Go array element is zeroed before decoding into it. // It fails with a [SemanticError] if the JSON array does not contain // the exact same number of elements as the Go array. -// It does not support any custom format flags. // // - A Go pointer is decoded based on the JSON kind and underlying Go type. // If the input is a JSON null, then this stores a nil pointer. // Otherwise, it allocates a new underlying value if the pointer is nil, // and recursively JSON decodes into the underlying value. -// Format flags are forwarded to the decoding of the underlying type. // // - A Go interface is decoded based on the JSON kind and underlying Go type. // If the input is a JSON null, then this stores a nil interface value. @@ -548,28 +485,15 @@ func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { // For example, unmarshaling into a nil io.Reader fails since // there is no concrete type to populate the interface value with. // Otherwise an underlying value exists and it recursively decodes -// the JSON input into it. It does not support any custom format flags. +// the JSON input into it. // // - A Go [time.Time] is decoded from a JSON string containing the time // formatted in RFC 3339 with nanosecond precision. -// If the format matches one of the format constants declared in -// the time package (e.g., RFC1123), then that format is used for parsing. -// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", -// then the timestamp is decoded from an optionally fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds) -// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. -// Otherwise, the format is used as-is with [time.Time.Parse] if non-empty. // // - A Go [time.Duration] currently has no default representation and -// requires an explicit format to be specified. -// If the format is "sec", "milli", "micro", or "nano", -// then the duration is decoded from an optionally fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds). -// If the format is "units", it is decoded from a JSON string parsed using -// [time.ParseDuration] (e.g., "1h30m" for 1 hour 30 minutes). -// If the format is "iso8601", it is decoded from a JSON string using the -// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) -// accepting only accurate units of hours, minutes, or seconds. +// results in a [SemanticError], unless the [encoding/json.FormatDurationAsNano] +// option is specified, in which case it is decoded as a JSON number +// without fractions or exponents, representing the duration in nanoseconds. // // - All other Go types (e.g., complex numbers, channels, and functions) // have no default representation and result in a [SemanticError]. @@ -580,6 +504,7 @@ func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { // For JSON objects, the input object is merged into the destination value // where matching object members recursively apply merge semantics. func Unmarshal(in []byte, out any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) return json.Unmarshal(in, out, opts...) } @@ -590,33 +515,25 @@ func Unmarshal(in []byte, out any, opts ...Options) (err error) { // without reporting an error for EOF. The output must be a non-nil pointer. // See [Unmarshal] for details about the conversion of JSON into a Go value. func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) return json.UnmarshalRead(in, out, opts...) } // UnmarshalDecode deserializes a Go value from a [jsontext.Decoder] according to -// the provided unmarshal options (while ignoring marshal, encode, or decode options). -// Any unmarshal options already specified on the [jsontext.Decoder] -// take lower precedence than the set of options provided by the caller. -// Unlike [Unmarshal] and [UnmarshalRead], decode options are ignored because -// they must have already been specified on the provided [jsontext.Decoder]. +// the provided unmarshal or decode options (while ignoring marshal or encode options). +// The options provided take precedence over options already applied on +// the [jsontext.Decoder] and only apply for the duration of the unmarshal call. // -// The input may be a stream of one or more JSON values, -// where this only unmarshals the next JSON value in the stream. +// The input may be a stream of zero or more JSON values. +// UnmarshalDecode unmarshals only the next JSON value in the stream. +// If there are no more top-level JSON values, it reports [io.EOF]. // The output must be a non-nil pointer. // See [Unmarshal] for details about the conversion of JSON into a Go value. func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) return json.UnmarshalDecode(in, out, opts...) } -// SkipFunc may be returned by [MarshalToFunc] and [UnmarshalFromFunc] functions. -// -// Any function that returns SkipFunc must not cause observable side effects -// on the provided [jsontext.Encoder] or [jsontext.Decoder]. -// For example, it is permissible to call [jsontext.Decoder.PeekKind], -// but not permissible to call [jsontext.Decoder.ReadToken] or -// [jsontext.Encoder.WriteToken] since such methods mutate the state. -var SkipFunc = json.SkipFunc - // Marshalers is a list of functions that may override the marshal behavior // of specific types. Populate [WithMarshalers] to use it with // [Marshal], [MarshalWrite], or [MarshalEncode]. @@ -627,7 +544,8 @@ type Marshalers = json.Marshalers // JoinMarshalers constructs a flattened list of marshal functions. // If multiple functions in the list are applicable for a value of a given type, // then those earlier in the list take precedence over those that come later. -// If a function returns [SkipFunc], then the next applicable function is called, +// If a function returns [errors.ErrUnsupported], +// then the next applicable function is called, // otherwise the default marshaling behavior is used. // // For example: @@ -649,7 +567,8 @@ type Unmarshalers = json.Unmarshalers // JoinUnmarshalers constructs a flattened list of unmarshal functions. // If multiple functions in the list are applicable for a value of a given type, // then those earlier in the list take precedence over those that come later. -// If a function returns [SkipFunc], then the next applicable function is called, +// If a function returns [errors.ErrUnsupported], +// then the next applicable function is called, // otherwise the default unmarshaling behavior is used. // // For example: @@ -667,9 +586,9 @@ func JoinUnmarshalers(us ...*Unmarshalers) *Unmarshalers { // The function is always provided with a non-nil pointer value // if T is an interface or pointer type. // -// The function must marshal exactly one JSON value. -// The value of T must not be retained outside the function call. -// It may not return [SkipFunc]. +// Implementations must follow the requirements of [Marshaler]. +// +// Implementations must not retain the value of T. func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers { return json.MarshalFunc[T](fn) } @@ -680,12 +599,10 @@ func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers { // The function is always provided with a non-nil pointer value // if T is an interface or pointer type. // -// The function must marshal exactly one JSON value by calling write methods -// on the provided encoder. It may return [SkipFunc] such that marshaling can -// move on to the next marshal function. However, no mutable method calls may -// be called on the encoder if [SkipFunc] is returned. -// The pointer to [jsontext.Encoder] and the value of T -// must not be retained outside the function call. +// Implementations must follow the requirements of [MarshalerTo]. +// +// Implementations must not retain the pointer to [jsontext.Encoder] or the +// value of T. func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers { return json.MarshalToFunc[T](fn) } @@ -695,10 +612,9 @@ func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers { // T must be an unnamed pointer or an interface type. // The function is always provided with a non-nil pointer value. // -// The function must unmarshal exactly one JSON value. -// The input []byte must not be mutated. -// The input []byte and value T must not be retained outside the function call. -// It may not return [SkipFunc]. +// Implementations must follow the requirements of [Unmarshaler]. +// +// Implementations must not retain the value of T. func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers { return json.UnmarshalFunc[T](fn) } @@ -708,60 +624,133 @@ func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers { // T must be an unnamed pointer or an interface type. // The function is always provided with a non-nil pointer value. // -// The function must unmarshal exactly one JSON value by calling read methods -// on the provided decoder. It may return [SkipFunc] such that unmarshaling can -// move on to the next unmarshal function. However, no mutable method calls may -// be called on the decoder if [SkipFunc] is returned. -// The pointer to [jsontext.Decoder] and the value of T -// must not be retained outside the function call. +// Implementations must follow the requirements of [UnmarshalerFrom]. +// +// Implementations must not retain the pointer to [jsontext.Decoder] or the +// value of T. func UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers { return json.UnmarshalFromFunc[T](fn) } // Marshaler is implemented by types that can marshal themselves. // It is recommended that types implement [MarshalerTo] unless the implementation -// is trying to avoid a hard dependency on the "jsontext" package. +// is trying to avoid directly depending on the "jsontext" package. // -// It is recommended that implementations return a buffer that is safe +// Implementations should return a buffer that is safe // for the caller to retain and potentially mutate. +// +// Implementations must not return [errors.ErrUnsupported]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError]. +// +// Implementations should assume [Deterministic] is true and return +// deterministic output. type Marshaler = json.Marshaler // MarshalerTo is implemented by types that can marshal themselves. // It is recommended that types implement MarshalerTo instead of [Marshaler] -// since this is both more performant and flexible. +// since it is both more performant and more flexible. // If a type implements both Marshaler and MarshalerTo, // then MarshalerTo takes precedence. In such a case, both implementations // should aim to have equivalent behavior for the default marshal options. // -// The implementation must write only one JSON value to the Encoder and -// must not retain the pointer to [jsontext.Encoder]. +// The implementation must write only one JSON value to the Encoder. +// Alternatively, it may return [errors.ErrUnsupported] without mutating +// the Encoder. The "json" package calling the method will +// use the next available JSON representation for the receiver type, +// as described in [Marshal]. +// Implementations must not retain the pointer to [jsontext.Encoder]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError], +// except for IO errors. +// +// The MarshalJSONTo method should not be called directly as it may +// return sentinel errors that need special handling. +// Users should instead call [MarshalEncode], which handles such cases. +// +// Implementations should inspect the marshal options from +// [jsontext.Encoder.Options] and adjust behavior to respect the options as +// necessary. +// +// The following options may be relevant to MarshalerTo implementations: +// +// - [Deterministic]: if the implementation may produce non-deterministic output +// - [StringifyNumbers]: if the type is represented as a JSON number +// +// Several options, such as [FormatNilSliceAsNull], apply only to native Go +// types. Thus, these options are typically not directly relevant to +// MarshalerTo implementations. However, types representing a composite type +// should marshal contained types using [MarshalEncode] to ensure these options +// apply to the contained types. Similarly, [WithMarshalers] may influence +// marshaling of any contained type within a composite type. +// +// All other options are automatically handled outside of the MarshalerTo +// implementation, and thus are not relevant to implementations. type MarshalerTo = json.MarshalerTo // Unmarshaler is implemented by types that can unmarshal themselves. // It is recommended that types implement [UnmarshalerFrom] unless the implementation -// is trying to avoid a hard dependency on the "jsontext" package. +// is trying to avoid a direct dependency on the "jsontext" package. // // The input can be assumed to be a valid encoding of a JSON value // if called from unmarshal functionality in this package. -// UnmarshalJSON must copy the JSON data if it is retained after returning. -// It is recommended that UnmarshalJSON implement merge semantics when -// unmarshaling into a pre-populated value. +// It is recommended that UnmarshalJSON implement merge semantics +// when unmarshaling into a pre-populated value, as described in [Unmarshal]. // // Implementations must not retain or mutate the input []byte. +// +// Implementations must not return [errors.ErrUnsupported]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError]. type Unmarshaler = json.Unmarshaler // UnmarshalerFrom is implemented by types that can unmarshal themselves. // It is recommended that types implement UnmarshalerFrom instead of [Unmarshaler] -// since this is both more performant and flexible. +// since this is both more performant and more flexible. // If a type implements both Unmarshaler and UnmarshalerFrom, // then UnmarshalerFrom takes precedence. In such a case, both implementations // should aim to have equivalent behavior for the default unmarshal options. // // The implementation must read only one JSON value from the Decoder. // It is recommended that UnmarshalJSONFrom implement merge semantics when -// unmarshaling into a pre-populated value. -// +// unmarshaling into a pre-populated value, as described in [Unmarshal]. +// Alternatively, it may return [errors.ErrUnsupported] without mutating +// the Decoder. The "json" package calling the method will +// use the next available JSON representation for the receiver type. // Implementations must not retain the pointer to [jsontext.Decoder]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError], +// except for [jsontext.SyntacticError]s and IO errors. +// +// The UnmarshalJSONFrom method should not be called directly as it may +// return sentinel errors that need special handling. +// Users should instead call [UnmarshalDecode], which handles such cases. +// +// Implementations should inspect the unmarshal options from +// [jsontext.Decoder.Options] and adjust behavior to respect the options as +// necessary. +// +// The following options may be relevant to UnmarshalerFrom implementations: +// +// - [StringifyNumbers]: if the type is represented as a JSON number +// +// Several options, such as [FormatNilSliceAsNull], apply only to native Go +// types. Thus, these options are typically not directly relevant to +// UnmarshalerFrom implementations. However, types representing a composite +// type should unmarshal contained types using [UnmarshalDecode] to ensure +// these options apply to the contained types. Similarly, [WithUnmarshalers] +// may influence unmarshaling of any contained type within a composite type. +// +// All other options are automatically handled outside of the UnmarshalerFrom +// implementation, and thus are not relevant to implementations. type UnmarshalerFrom = json.UnmarshalerFrom // ErrUnknownName indicates that a JSON object member could not be @@ -771,8 +760,8 @@ type UnmarshalerFrom = json.UnmarshalerFrom // The name of an unknown JSON object member can be extracted as: // // err := ... -// var serr json.SemanticError -// if errors.As(err, &serr) && serr.Err == json.ErrUnknownName { +// serr, ok := errors.AsType[*json.SemanticError](err) +// if ok && serr.Err == json.ErrUnknownName { // ptr := serr.JSONPointer // JSON pointer to unknown name // name := ptr.LastToken() // unknown name itself // ... @@ -782,7 +771,12 @@ type UnmarshalerFrom = json.UnmarshalerFrom var ErrUnknownName = json.ErrUnknownName // SemanticError describes an error determining the meaning -// of JSON data as Go data or vice-versa. +// of JSON data as Go data, or vice versa. +// +// If a [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom] method +// returns a SemanticError when called by the [json] package, +// then the ByteOffset, JSONPointer, and GoType fields are automatically +// populated by the calling context if they are the zero value. // // The contents of this error as produced by this package may change over time. type SemanticError = json.SemanticError @@ -796,11 +790,11 @@ type SemanticError = json.SemanticError // [encoding/json/jsontext.Options]. Options from the other packages can // be used interchangeably with functionality in this package. // -// Options represent either a singular option or a set of options. -// It can be functionally thought of as a Go map of option properties +// An Options value represents either a single option or a set of options. +// It can be thought of as a Go map of option properties // (even though the underlying implementation avoids Go maps for performance). // -// The constructors (e.g., [Deterministic]) return a singular option value: +// The constructors (e.g., [Deterministic]) return a value for a single option: // // opt := Deterministic(true) // @@ -808,7 +802,7 @@ type SemanticError = json.SemanticError // // opt := Options{"Deterministic": true} // -// [JoinOptions] composes multiple options values to together: +// [JoinOptions] composes multiple options values together: // // out := JoinOptions(opts...) // @@ -821,7 +815,7 @@ type SemanticError = json.SemanticError // } // } // -// [GetOption] looks up the value of options parameter: +// [GetOption] looks up the value of an options parameter: // // v, ok := GetOption(opts, Deterministic) // @@ -838,7 +832,6 @@ type SemanticError = json.SemanticError // - [FormatNilMapAsNull] affects marshaling only // - [OmitZeroStructFields] affects marshaling only // - [MatchCaseInsensitiveNames] affects marshaling and unmarshaling -// - [DiscardUnknownMembers] affects marshaling only // - [RejectUnknownMembers] affects unmarshaling only // - [WithMarshalers] affects marshaling only // - [WithUnmarshalers] affects unmarshaling only @@ -854,6 +847,7 @@ func JoinOptions(srcs ...Options) Options { // GetOption returns the value stored in opts with the provided setter, // reporting whether the value is present. +// If not present, the returned value is the zero value for type T. // // Example usage: // @@ -868,18 +862,33 @@ func GetOption[T any](opts Options, setter func(T) Options) (T, bool) { } // DefaultOptionsV2 is the full set of all options that define v2 semantics. -// It is equivalent to all options under [Options], [encoding/json.Options], -// and [encoding/json/jsontext.Options] being set to false or the zero value, -// except for the options related to whitespace formatting. +// It is equivalent to the set of options in [encoding/json.DefaultOptionsV1] +// all being set to false. All other options are not present. func DefaultOptionsV2() Options { return json.DefaultOptionsV2() } -// StringifyNumbers specifies that numeric Go types should be marshaled -// as a JSON string containing the equivalent JSON number value. -// When unmarshaling, numeric Go types are parsed from a JSON string +// StringifyNumbers specifies that types that would normally be +// encoded as a JSON number instead be encoded as a JSON string +// containing the equivalent JSON number value. +// When unmarshaling, the value is parsed from a JSON string // containing the JSON number without any surrounding whitespace. // +// Specifying the `string` tag option on a Go struct field applies this option +// to the top-level JSON value for that field. When applied via the `string` +// tag option, StringifyNumbers option does not recursively apply to nested +// JSON numbers within a JSON object or array. +// +// Like all options, explicitly specifying this option in a call to [Marshal], +// [Unmarshal], etc, will apply recursively. +// +// A Go type with custom marshal/unmarshal that represents a JSON number +// should respect the StringifyNumbers option and if specified +// serialize as a JSON number within a JSON string. +// Custom marshal/unmarshal should handle nested JSON objects using +// [MarshalEncode]/[UnmarshalDecode], which will automatically apply the +// non-recursive `string` tag option behavior. +// // According to RFC 8259, section 6, a JSON implementation may choose to // limit the representation of a JSON number to an IEEE 754 binary64 value. // This may cause decoders to lose precision for int64 and uint64 types. @@ -890,11 +899,18 @@ func StringifyNumbers(v bool) Options { return json.StringifyNumbers(v) } -// Deterministic specifies that the same input value will be serialized -// as the exact same output bytes. Different processes of -// the same program will serialize equal values to the same bytes, -// but different versions of the same program are not guaranteed -// to produce the exact same sequence of bytes. +// Deterministic specifies that marshaling the same input value will always +// serialize as the same output bytes. +// +// For example, Go maps are marshaled sorted by key. +// +// For native Go types, Determinism is guaranteed across different instances of +// identical binaries, but not across different builds of a program (such as +// different source or toolchain version, different GOOS/GOARCH, different +// build flags). +// +// A Go type with a custom marshaler should also respect the Deterministic +// option and serialize deterministically if it is true. // // This only affects marshaling and is ignored when unmarshaling. func Deterministic(v bool) Options { @@ -904,8 +920,6 @@ func Deterministic(v bool) Options { // FormatNilSliceAsNull specifies that a nil Go slice should marshal as a // JSON null instead of the default representation as an empty JSON array // (or an empty JSON string in the case of ~[]byte). -// Slice fields explicitly marked with `format:emitempty` still marshal -// as an empty JSON array. // // This only affects marshaling and is ignored when unmarshaling. func FormatNilSliceAsNull(v bool) Options { @@ -914,19 +928,17 @@ func FormatNilSliceAsNull(v bool) Options { // FormatNilMapAsNull specifies that a nil Go map should marshal as a // JSON null instead of the default representation as an empty JSON object. -// Map fields explicitly marked with `format:emitempty` still marshal -// as an empty JSON object. // // This only affects marshaling and is ignored when unmarshaling. func FormatNilMapAsNull(v bool) Options { return json.FormatNilMapAsNull(v) } -// OmitZeroStructFields specifies that a Go struct should marshal in such a way -// that all struct fields that are zero are omitted from the marshaled output -// if the value is zero as determined by the "IsZero() bool" method if present, -// otherwise based on whether the field is the zero Go value. -// This is semantically equivalent to specifying the `omitzero` tag option +// OmitZeroStructFields specifies that zero-valued fields of Go struct should be +// omitted from the marshaled output. +// A value is considered zero if its type has an "IsZero() bool" method that returns true, +// or if it lacks such a method and the value is a Go zero value. +// This option is equivalent to specifying the `omitzero` tag option // on every field in a Go struct. // // This only affects marshaling and is ignored when unmarshaling. @@ -936,30 +948,31 @@ func OmitZeroStructFields(v bool) Options { // MatchCaseInsensitiveNames specifies that JSON object members are matched // against Go struct fields using a case-insensitive match of the name. +// If a name matches multiple fields, the field whose name matches exactly is chosen. +// If there is none, an error is reported. // Go struct fields explicitly marked with `case:strict` or `case:ignore` // always use case-sensitive (or case-insensitive) name matching, // regardless of the value of this option. // // This affects either marshaling or unmarshaling. -// For marshaling, this option may alter the detection of duplicate names -// (assuming [jsontext.AllowDuplicateNames] is false) from inlined fields -// if it matches one of the declared fields in the Go struct. +// +// Matching names case-insensitively also affects duplicate name detection +// (assuming [jsontext.AllowDuplicateNames] is false) since +// variations of the same name may match the same Go struct field. +// For example, when unmarshaling, the names "foo" and "Foo" may both +// match the same Go struct field and therefore be considered a duplicate name. +// When marshaling, normally it is impossible for any two Go struct fields to +// serialize in a way where they unmarshal into the same Go struct field +// since they all have unique exact names. +// However, it is possible for an +// embedded fallback to contain a name that also matches the name for +// a Go struct field, resulting in a duplicate name error. func MatchCaseInsensitiveNames(v bool) Options { return json.MatchCaseInsensitiveNames(v) } -// DiscardUnknownMembers specifies that marshaling should ignore any -// JSON object members stored in Go struct fields dedicated to storing -// unknown JSON object members. -// -// This only affects marshaling and is ignored when unmarshaling. -func DiscardUnknownMembers(v bool) Options { - return json.DiscardUnknownMembers(v) -} - // RejectUnknownMembers specifies that unknown members should be rejected -// when unmarshaling a JSON object, regardless of whether there is a field -// to store unknown members. +// when unmarshaling a JSON object. // // This only affects unmarshaling and is ignored when marshaling. func RejectUnknownMembers(v bool) Options { diff --git a/vendor/github.com/go-json-experiment/json/arshal.go b/vendor/github.com/go-json-experiment/json/arshal.go index be24cb8..76b4af0 100644 --- a/vendor/github.com/go-json-experiment/json/arshal.go +++ b/vendor/github.com/go-json-experiment/json/arshal.go @@ -9,10 +9,9 @@ package json import ( "bytes" "encoding" + "errors" "io" "reflect" - "slices" - "strings" "sync" "time" @@ -32,6 +31,36 @@ var ( _ time.Duration ) +var ( + // Once a JSON object has begun processing without duplicate name verification, + // it does not track the history of names that have been seen so far. + // Reject changing the setting for the current JSON object namespace, + // otherwise we would be operating with inconsistent state. + // Note that you can change the setting before processing the start + // of a different JSON object. + // + // TODO: We could loosen this restriction in certain conditions. + // If we are already checking for duplicate names, + // we can momentarily disable it for the next JSON object member name. + // However, if we are already NOT checking for duplicate names, + // we cannot momentarily enable it for the next JSON object member name + // since we already lack prior history of JSON object names. + errChangingDuplicateNames = errors.New("cannot change duplicate name checks after a JSON object has already begun processing") + + // The presence of invalid UTF-8 has an interesting intersection + // with checking for duplicate names. Due to the semantic of mangling + // invalid UTF-8 as the Unicode replacement character, + // two string keys in a Go map (both with invalid UTF-8) + // may encode as the same JSON string. Thus, we forbid changing of + // invalid UTF-8 checks in the current JSON object namespace. + errChangingInvalidUTF8 = errors.New("cannot change UTF-8 checks after a JSON object has already begun processing") + + // TODO(https://go.dev/issue/79559): Changing whitespace currently + // leads to strange effects and will need more careful adjustment. + // For now, we just report an error. + errChangingWhitespace = errors.New("cannot change whitespace formatting within a MarshalEncode call") +) + // export exposes internal functionality of the "jsontext" package. var export = jsontext.Internal.Export(&internal.AllowInternalUse) @@ -44,19 +73,21 @@ var export = jsontext.Internal.Export(&internal.AllowInternalUse) // Functions or methods that operate on *T are only called when encoding // a value of type T (by taking its address) or a non-nil value of *T. // Marshal ensures that a value is always addressable -// (by boxing it on the heap if necessary) so that +// (by copying the value if necessary) so that // these functions and methods can be consistently called. For performance, // it is recommended that Marshal be passed a non-nil pointer to the value. // -// The input value is encoded as JSON according the following rules: +// The input value is encoded as JSON according to the following rules: // // - If any type-specific functions in a [WithMarshalers] option match // the value type, then those functions are called to encode the value. -// If all applicable functions return [SkipFunc], +// If all applicable functions return [errors.ErrUnsupported], // then the value is encoded according to subsequent rules. // // - If the value type implements [MarshalerTo], // then the MarshalJSONTo method is called to encode the value. +// If the method returns [errors.ErrUnsupported], +// then the input is encoded according to subsequent rules. // // - If the value type implements [Marshaler], // then the MarshalJSON method is called to encode the value. @@ -72,51 +103,31 @@ var export = jsontext.Internal.Export(&internal.AllowInternalUse) // - Otherwise, the value is encoded according to the value's type // as described in detail below. // -// Most Go types have a default JSON representation. -// Certain types support specialized formatting according to -// a format flag optionally specified in the Go struct tag -// for the struct field that contains the current value -// (see the “JSON Representation of Go structs” section for more details). -// -// The representation of each type is as follows: +// Most Go types have a default JSON representation as follows: // // - A Go boolean is encoded as a JSON boolean (e.g., true or false). -// It does not support any custom format flags. // // - A Go string is encoded as a JSON string. -// It does not support any custom format flags. // // - A Go []byte or [N]byte is encoded as a JSON string containing -// the binary value encoded using RFC 4648. -// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. -// If the format is "base64url", then this uses RFC 4648, section 5. -// If the format is "base32", then this uses RFC 4648, section 6. -// If the format is "base32hex", then this uses RFC 4648, section 7. -// If the format is "base16" or "hex", then this uses RFC 4648, section 8. -// If the format is "array", then the bytes value is encoded as a JSON array -// where each byte is recursively JSON-encoded as each JSON array element. +// a binary value using Base 64 Encoding per RFC 4648, section 4. // // - A Go integer is encoded as a JSON number without fractions or exponents. // If [StringifyNumbers] is specified or encoding a JSON object name, // then the JSON number is encoded within a JSON string. -// It does not support any custom format flags. // // - A Go float is encoded as a JSON number. // If [StringifyNumbers] is specified or encoding a JSON object name, // then the JSON number is encoded within a JSON string. -// If the format is "nonfinite", then NaN, +Inf, and -Inf are encoded as -// the JSON strings "NaN", "Infinity", and "-Infinity", respectively. -// Otherwise, the presence of non-finite numbers results in a [SemanticError]. +// Encoding a NaN or ±Inf results in a [SemanticError]. // // - A Go map is encoded as a JSON object, where each Go map key and value // is recursively encoded as a name and value pair in the JSON object. // The Go map key must encode as a JSON string, otherwise this results // in a [SemanticError]. The Go map is traversed in a non-deterministic order. // For deterministic encoding, consider using the [Deterministic] option. -// If the format is "emitnull", then a nil map is encoded as a JSON null. -// If the format is "emitempty", then a nil map is encoded as an empty JSON object, -// regardless of whether [FormatNilMapAsNull] is specified. -// Otherwise by default, a nil map is encoded as an empty JSON object. +// By default, a nil map is encoded as an empty JSON object, +// unless the [FormatNilMapAsNull] option is specified. // // - A Go struct is encoded as a JSON object. // See the “JSON Representation of Go structs” section @@ -124,53 +135,33 @@ var export = jsontext.Internal.Export(&internal.AllowInternalUse) // // - A Go slice is encoded as a JSON array, where each Go slice element // is recursively JSON-encoded as the elements of the JSON array. -// If the format is "emitnull", then a nil slice is encoded as a JSON null. -// If the format is "emitempty", then a nil slice is encoded as an empty JSON array, -// regardless of whether [FormatNilSliceAsNull] is specified. -// Otherwise by default, a nil slice is encoded as an empty JSON array. +// By default, a nil slice is encoded as an empty JSON array, +// unless the [FormatNilSliceAsNull] option is specified. // // - A Go array is encoded as a JSON array, where each Go array element // is recursively JSON-encoded as the elements of the JSON array. // The JSON array length is always identical to the Go array length. -// It does not support any custom format flags. // // - A Go pointer is encoded as a JSON null if nil, otherwise it is // the recursively JSON-encoded representation of the underlying value. -// Format flags are forwarded to the encoding of the underlying value. // // - A Go interface is encoded as a JSON null if nil, otherwise it is // the recursively JSON-encoded representation of the underlying value. -// It does not support any custom format flags. // // - A Go [time.Time] is encoded as a JSON string containing the timestamp // formatted in RFC 3339 with nanosecond precision. -// If the format matches one of the format constants declared -// in the time package (e.g., RFC1123), then that format is used. -// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", -// then the timestamp is encoded as a possibly fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds) -// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. -// To avoid a fractional component, round the timestamp to the relevant unit. -// Otherwise, the format is used as-is with [time.Time.Format] if non-empty. // // - A Go [time.Duration] currently has no default representation and -// requires an explicit format to be specified. -// If the format is "sec", "milli", "micro", or "nano", -// then the duration is encoded as a possibly fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds). -// To avoid a fractional component, round the duration to the relevant unit. -// If the format is "units", it is encoded as a JSON string formatted using -// [time.Duration.String] (e.g., "1h30m" for 1 hour 30 minutes). -// If the format is "iso8601", it is encoded as a JSON string using the -// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) -// using only accurate units of hours, minutes, and seconds. +// results in a [SemanticError], unless the [encoding/json.FormatDurationAsNano] +// option is specified, in which case it is encoded as a JSON number +// without fractions or exponents, representing the duration in nanoseconds. // // - All other Go types (e.g., complex numbers, channels, and functions) // have no default representation and result in a [SemanticError]. // // JSON cannot represent cyclic data structures and Marshal does not handle them. -// Passing cyclic structures will result in an error. func Marshal(in any, opts ...Options) (out []byte, err error) { + opts = mayAppendSupportFormatTag(opts) enc := export.GetBufferedEncoder(opts...) defer export.PutBufferedEncoder(enc) xe := export.Encoder(enc) @@ -187,6 +178,7 @@ func Marshal(in any, opts ...Options) (out []byte, err error) { // It does not terminate the output with a newline. // See [Marshal] for details about the conversion of a Go value into JSON. func MarshalWrite(out io.Writer, in any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) enc := export.GetStreamingEncoder(out, opts...) defer export.PutStreamingEncoder(enc) xe := export.Encoder(enc) @@ -199,19 +191,34 @@ func MarshalWrite(out io.Writer, in any, opts ...Options) (err error) { } // MarshalEncode serializes a Go value into an [jsontext.Encoder] according to -// the provided marshal options (while ignoring unmarshal, encode, or decode options). -// Any marshal-relevant options already specified on the [jsontext.Encoder] -// take lower precedence than the set of options provided by the caller. -// Unlike [Marshal] and [MarshalWrite], encode options are ignored because -// they must have already been specified on the provided [jsontext.Encoder]. +// the provided marshal or encode options (while ignoring unmarshal or decode options). +// The options provided take precedence over options already applied on +// the [jsontext.Encoder] and only apply for the duration of the marshal call. // // See [Marshal] for details about the conversion of a Go value into JSON. func MarshalEncode(out *jsontext.Encoder, in any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) xe := export.Encoder(out) if len(opts) > 0 { optsOriginal := xe.Struct defer func() { xe.Struct = optsOriginal }() - xe.Struct.JoinWithoutCoderOptions(opts...) + xe.Struct.Join(opts...) + if xe.Tokens.Last.NeedObjectName() { + if optsOriginal.Flags.Get(jsonflags.AllowDuplicateNames) != xe.Struct.Flags.Get(jsonflags.AllowDuplicateNames) { + return newMarshalErrorBefore(out, reflect.TypeOf(in), errChangingDuplicateNames) + } + if optsOriginal.Flags.Get(jsonflags.AllowInvalidUTF8) != xe.Struct.Flags.Get(jsonflags.AllowInvalidUTF8) { + return newMarshalErrorBefore(out, reflect.TypeOf(in), errChangingInvalidUTF8) + } + } + if xe.Struct.Flags.Has(jsonflags.AnyWhitespace) { + if xe.Struct.Flags.Get(jsonflags.Multiline) { + xe.Struct.InitializeMultiline() + } + if jsonopts.ChangedWhitespace(optsOriginal, xe.Struct) { + return newMarshalErrorBefore(out, reflect.TypeOf(in), errChangingWhitespace) + } + } } err = marshalEncode(out, in, &xe.Struct) if err != nil && xe.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { @@ -260,18 +267,24 @@ func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err erro // Functions or methods that operate on *T are only called when decoding // a value of type T (by taking its address) or a non-nil value of *T. // Unmarshal ensures that a value is always addressable -// (by boxing it on the heap if necessary) so that +// (by copying the value if necessary) so that // these functions and methods can be consistently called. +// If a value must be shallow copied to call a pointer-receiver +// [Unmarshaler], [UnmarshalerFrom], or [encoding.TextUnmarshaler] method, +// then any mutations performed by the method are shallow copied back +// into the destination value. // -// The input is decoded into the output according the following rules: +// The input is decoded into the output according to the following rules: // // - If any type-specific functions in a [WithUnmarshalers] option match // the value type, then those functions are called to decode the JSON -// value. If all applicable functions return [SkipFunc], +// value. If all applicable functions return [errors.ErrUnsupported], // then the input is decoded according to subsequent rules. // // - If the value type implements [UnmarshalerFrom], // then the UnmarshalJSONFrom method is called to decode the JSON value. +// If the method returns [errors.ErrUnsupported], +// then the input is decoded according to subsequent rules. // // - If the value type implements [Unmarshaler], // then the UnmarshalJSON method is called to decode the JSON value. @@ -285,10 +298,6 @@ func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err erro // as described in detail below. // // Most Go types have a default JSON representation. -// Certain types support specialized formatting according to -// a format flag optionally specified in the Go struct tag -// for the struct field that contains the current value -// (see the “JSON Representation of Go structs” section for more details). // A JSON null may be decoded into every supported Go value where // it is equivalent to storing the zero value of the Go value. // If the input JSON kind is not handled by the current Go value type, @@ -298,20 +307,11 @@ func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err erro // The representation of each type is as follows: // // - A Go boolean is decoded from a JSON boolean (e.g., true or false). -// It does not support any custom format flags. // // - A Go string is decoded from a JSON string. -// It does not support any custom format flags. // -// - A Go []byte or [N]byte is decoded from a JSON string -// containing the binary value encoded using RFC 4648. -// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. -// If the format is "base64url", then this uses RFC 4648, section 5. -// If the format is "base32", then this uses RFC 4648, section 6. -// If the format is "base32hex", then this uses RFC 4648, section 7. -// If the format is "base16" or "hex", then this uses RFC 4648, section 8. -// If the format is "array", then the Go slice or array is decoded from a -// JSON array where each JSON element is recursively decoded for each byte. +// - A Go []byte or [N]byte is decoded from a JSON string containing +// a binary value using Base 64 Encoding per RFC 4648, section 4. // When decoding into a non-nil []byte, the slice length is reset to zero // and the decoded input is appended to it. // When decoding into a [N]byte, the input must decode to exactly N bytes, @@ -323,15 +323,13 @@ func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err erro // It fails with a [SemanticError] if the JSON number // has a fractional or exponent component. // It also fails if it overflows the representation of the Go integer type. -// It does not support any custom format flags. // // - A Go float is decoded from a JSON number. // It must be decoded from a JSON string containing a JSON number // if [StringifyNumbers] is specified or decoding a JSON object name. // It fails if it overflows the representation of the Go float type. -// If the format is "nonfinite", then the JSON strings -// "NaN", "Infinity", and "-Infinity" are decoded as NaN, +Inf, and -Inf. -// Otherwise, the presence of such strings results in a [SemanticError]. +// Since JSON lacks a native representation for a NaN or ±Inf, +// such values cannot be the result of decoding. // // - A Go map is decoded from a JSON object, // where each JSON object name and value pair is recursively decoded @@ -339,7 +337,6 @@ func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err erro // If the Go map is nil, then a new map is allocated to decode into. // If the decoded key matches an existing Go map entry, the entry value // is reused by decoding the JSON object value into it. -// The formats "emitnull" and "emitempty" have no effect when decoding. // // - A Go struct is decoded from a JSON object. // See the “JSON Representation of Go structs” section @@ -349,20 +346,17 @@ func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err erro // is recursively decoded and appended to the Go slice. // Before appending into a Go slice, a new slice is allocated if it is nil, // otherwise the slice length is reset to zero. -// The formats "emitnull" and "emitempty" have no effect when decoding. // // - A Go array is decoded from a JSON array, where each JSON array element // is recursively decoded as each corresponding Go array element. // Each Go array element is zeroed before decoding into it. // It fails with a [SemanticError] if the JSON array does not contain // the exact same number of elements as the Go array. -// It does not support any custom format flags. // // - A Go pointer is decoded based on the JSON kind and underlying Go type. // If the input is a JSON null, then this stores a nil pointer. // Otherwise, it allocates a new underlying value if the pointer is nil, // and recursively JSON decodes into the underlying value. -// Format flags are forwarded to the decoding of the underlying type. // // - A Go interface is decoded based on the JSON kind and underlying Go type. // If the input is a JSON null, then this stores a nil interface value. @@ -374,28 +368,15 @@ func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err erro // For example, unmarshaling into a nil io.Reader fails since // there is no concrete type to populate the interface value with. // Otherwise an underlying value exists and it recursively decodes -// the JSON input into it. It does not support any custom format flags. +// the JSON input into it. // // - A Go [time.Time] is decoded from a JSON string containing the time // formatted in RFC 3339 with nanosecond precision. -// If the format matches one of the format constants declared in -// the time package (e.g., RFC1123), then that format is used for parsing. -// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", -// then the timestamp is decoded from an optionally fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds) -// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. -// Otherwise, the format is used as-is with [time.Time.Parse] if non-empty. // // - A Go [time.Duration] currently has no default representation and -// requires an explicit format to be specified. -// If the format is "sec", "milli", "micro", or "nano", -// then the duration is decoded from an optionally fractional JSON number -// of the number of seconds (or milliseconds, microseconds, or nanoseconds). -// If the format is "units", it is decoded from a JSON string parsed using -// [time.ParseDuration] (e.g., "1h30m" for 1 hour 30 minutes). -// If the format is "iso8601", it is decoded from a JSON string using the -// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) -// accepting only accurate units of hours, minutes, or seconds. +// results in a [SemanticError], unless the [encoding/json.FormatDurationAsNano] +// option is specified, in which case it is decoded as a JSON number +// without fractions or exponents, representing the duration in nanoseconds. // // - All other Go types (e.g., complex numbers, channels, and functions) // have no default representation and result in a [SemanticError]. @@ -406,6 +387,7 @@ func marshalEncode(out *jsontext.Encoder, in any, mo *jsonopts.Struct) (err erro // For JSON objects, the input object is merged into the destination value // where matching object members recursively apply merge semantics. func Unmarshal(in []byte, out any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) dec := export.GetBufferedDecoder(in, opts...) defer export.PutBufferedDecoder(dec) xd := export.Decoder(dec) @@ -423,6 +405,7 @@ func Unmarshal(in []byte, out any, opts ...Options) (err error) { // without reporting an error for EOF. The output must be a non-nil pointer. // See [Unmarshal] for details about the conversion of JSON into a Go value. func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) dec := export.GetStreamingDecoder(in, opts...) defer export.PutStreamingDecoder(dec) xd := export.Decoder(dec) @@ -434,22 +417,30 @@ func UnmarshalRead(in io.Reader, out any, opts ...Options) (err error) { } // UnmarshalDecode deserializes a Go value from a [jsontext.Decoder] according to -// the provided unmarshal options (while ignoring marshal, encode, or decode options). -// Any unmarshal options already specified on the [jsontext.Decoder] -// take lower precedence than the set of options provided by the caller. -// Unlike [Unmarshal] and [UnmarshalRead], decode options are ignored because -// they must have already been specified on the provided [jsontext.Decoder]. +// the provided unmarshal or decode options (while ignoring marshal or encode options). +// The options provided take precedence over options already applied on +// the [jsontext.Decoder] and only apply for the duration of the unmarshal call. // -// The input may be a stream of one or more JSON values, -// where this only unmarshals the next JSON value in the stream. +// The input may be a stream of zero or more JSON values. +// UnmarshalDecode unmarshals only the next JSON value in the stream. +// If there are no more top-level JSON values, it reports [io.EOF]. // The output must be a non-nil pointer. // See [Unmarshal] for details about the conversion of JSON into a Go value. func UnmarshalDecode(in *jsontext.Decoder, out any, opts ...Options) (err error) { + opts = mayAppendSupportFormatTag(opts) xd := export.Decoder(in) if len(opts) > 0 { optsOriginal := xd.Struct defer func() { xd.Struct = optsOriginal }() - xd.Struct.JoinWithoutCoderOptions(opts...) + xd.Struct.Join(opts...) + if xd.Tokens.Last.NeedObjectName() { + if optsOriginal.Flags.Get(jsonflags.AllowDuplicateNames) != xd.Struct.Flags.Get(jsonflags.AllowDuplicateNames) { + return newUnmarshalErrorBefore(in, reflect.TypeOf(out), errChangingDuplicateNames) + } + if optsOriginal.Flags.Get(jsonflags.AllowInvalidUTF8) != xd.Struct.Flags.Get(jsonflags.AllowInvalidUTF8) { + return newUnmarshalErrorBefore(in, reflect.TypeOf(out), errChangingInvalidUTF8) + } + } } err = unmarshalDecode(in, out, &xd.Struct, false) if err != nil && xd.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { @@ -523,7 +514,7 @@ func newAddressableValue(t reflect.Type) addressableValue { // This can be directly accessed on the encoder or decoder. // All marshal and unmarshal behavior is implemented using these signatures. -// The *jsonopts.Struct argument is guaranteed to identical to or at least +// The *jsonopts.Struct argument is guaranteed to be identical to or at least // a strict super-set of the options in Encoder.Struct or Decoder.Struct. // It is identical for Marshal, Unmarshal, MarshalWrite, and UnmarshalRead. // It is a super-set for MarshalEncode and UnmarshalDecode. @@ -572,9 +563,6 @@ func putStrings(s *stringSlice) { if cap(*s) > 1<<10 { *s = nil // avoid pinning arbitrarily large amounts of memory } + clear(*s) // avoid pinning a reference to each string stringsPools.Put(s) } - -func (ss *stringSlice) Sort() { - slices.SortFunc(*ss, func(x, y string) int { return strings.Compare(x, y) }) -} diff --git a/vendor/github.com/go-json-experiment/json/arshal_any.go b/vendor/github.com/go-json-experiment/json/arshal_any.go index 5015587..77a6b35 100644 --- a/vendor/github.com/go-json-experiment/json/arshal_any.go +++ b/vendor/github.com/go-json-experiment/json/arshal_any.go @@ -8,7 +8,10 @@ package json import ( "cmp" + "errors" + "math" "reflect" + "slices" "strconv" "github.com/go-json-experiment/json/internal" @@ -35,20 +38,23 @@ func marshalValueAny(enc *jsontext.Encoder, val any, mo *jsonopts.Struct) error case string: return enc.WriteToken(jsontext.String(val)) case float64: + if math.IsNaN(val) || math.IsInf(val, 0) { + break // use default logic below + } return enc.WriteToken(jsontext.Float(val)) case map[string]any: return marshalObjectAny(enc, val, mo) case []any: return marshalArrayAny(enc, val, mo) - default: - v := newAddressableValue(reflect.TypeOf(val)) - v.Set(reflect.ValueOf(val)) - marshal := lookupArshaler(v.Type()).marshal - if mo.Marshalers != nil { - marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, v.Type()) - } - return marshal(enc, v, mo) } + + v := newAddressableValue(reflect.TypeOf(val)) + v.Set(reflect.ValueOf(val)) + marshal := lookupArshaler(v.Type()).marshal + if mo.Marshalers != nil { + marshal, _ = mo.Marshalers.(*Marshalers).lookup(marshal, v.Type()) + } + return marshal(enc, v, mo) } // unmarshalValueAny unmarshals a JSON value as a Go any. @@ -85,9 +91,9 @@ func unmarshalValueAny(dec *jsontext.Decoder, uo *jsonopts.Struct) (any, error) if uo.Flags.Get(jsonflags.UnmarshalAnyWithRawNumber) { return internal.RawNumberOf(val), nil } - fv, ok := jsonwire.ParseFloat(val, 64) - if !ok { - return fv, newUnmarshalErrorAfterWithValue(dec, float64Type, strconv.ErrRange) + fv, err := strconv.ParseFloat(string(val), 64) + if err != nil { + return fv, newUnmarshalErrorAfterWithValue(dec, float64Type, errors.Unwrap(err)) } return fv, nil default: @@ -104,7 +110,7 @@ func marshalObjectAny(enc *jsontext.Encoder, obj map[string]any, mo *jsonopts.St if xe.Tokens.Depth() > startDetectingCyclesAfter { v := reflect.ValueOf(obj) if err := visitPointer(&xe.SeenPointers, v); err != nil { - return newMarshalErrorBefore(enc, anyType, err) + return newMarshalErrorBefore(enc, mapStringAnyType, err) } defer leavePointer(&xe.SeenPointers, v) } @@ -128,7 +134,7 @@ func marshalObjectAny(enc *jsontext.Encoder, obj map[string]any, mo *jsonopts.St if err := enc.WriteToken(jsontext.BeginObject); err != nil { return err } - // A Go map guarantees that each entry has a unique key + // A Go map guarantees that each entry has a unique key. // The only possibility of duplicates is due to invalid UTF-8. if !mo.Flags.Get(jsonflags.AllowInvalidUTF8) { xe.Tokens.Last.DisableNamespace() @@ -149,7 +155,7 @@ func marshalObjectAny(enc *jsontext.Encoder, obj map[string]any, mo *jsonopts.St (*names)[i] = name i++ } - names.Sort() + slices.Sort(*names) for _, name := range *names { if err := enc.WriteToken(jsontext.String(name)); err != nil { return err @@ -176,7 +182,7 @@ func unmarshalObjectAny(dec *jsontext.Decoder, uo *jsonopts.Struct) (map[string] panic("BUG: invalid kind: " + tok.Kind().String()) } obj := make(map[string]any) - // A Go map guarantees that each entry has a unique key + // A Go map guarantees that each entry has a unique key. // The only possibility of duplicates is due to invalid UTF-8. if !uo.Flags.Get(jsonflags.AllowInvalidUTF8) { export.Decoder(dec).Tokens.Last.DisableNamespace() diff --git a/vendor/github.com/go-json-experiment/json/arshal_default.go b/vendor/github.com/go-json-experiment/json/arshal_default.go index 7924265..bbb4688 100644 --- a/vendor/github.com/go-json-experiment/json/arshal_default.go +++ b/vendor/github.com/go-json-experiment/json/arshal_default.go @@ -35,7 +35,7 @@ import ( const optimizeCommon = true var ( - // Most natural Go type that correspond with each JSON type. + // Most natural Go types that correspond with each JSON type. anyType = reflect.TypeFor[any]() // JSON value boolType = reflect.TypeFor[bool]() // JSON bool stringType = reflect.TypeFor[string]() // JSON string @@ -127,12 +127,19 @@ func makeBoolArshaler(t reflect.Type) *arshaler { var fncs arshaler fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { xe := export.Encoder(enc) - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - return newInvalidFormatError(enc, t, mo) + var stringify bool // always false except `string` tag with StringifyWithLegacySemantics + if mo.Flags.Has(jsonflags.TagFlags) { + stringify = mo.Flags.Get(jsonflags.StringTag) && mo.Flags.Get(jsonflags.StringifyWithLegacySemantics) + if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + } + if mo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(enc, t) + } } // Optimize for marshaling without preceding whitespace. - if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyBoolsAndStrings) && !xe.Tokens.Last.NeedObjectName() { + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify && !xe.Tokens.Last.NeedObjectName() { xe.Buf = strconv.AppendBool(xe.Tokens.MayAppendDelim(xe.Buf, 't'), va.Bool()) xe.Tokens.Last.Increment() if xe.NeedFlush() { @@ -141,7 +148,7 @@ func makeBoolArshaler(t reflect.Type) *arshaler { return nil } - if mo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { + if stringify { if va.Bool() { return enc.WriteToken(jsontext.String("true")) } else { @@ -151,9 +158,15 @@ func makeBoolArshaler(t reflect.Type) *arshaler { return enc.WriteToken(jsontext.Bool(va.Bool())) } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { - xd := export.Decoder(dec) - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - return newInvalidFormatError(dec, t, uo) + var stringify bool // always false except `string` tag with StringifyWithLegacySemantics + if uo.Flags.Has(jsonflags.TagFlags) { + stringify = uo.Flags.Get(jsonflags.StringTag) && uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) + if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + } + if uo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(dec, t) + } } tok, err := dec.ReadToken() if err != nil { @@ -167,12 +180,12 @@ func makeBoolArshaler(t reflect.Type) *arshaler { } return nil case 't', 'f': - if !uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { + if !stringify { va.SetBool(tok.Bool()) return nil } case '"': - if uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { + if stringify { switch tok.String() { case "true": va.SetBool(true) @@ -190,7 +203,7 @@ func makeBoolArshaler(t reflect.Type) *arshaler { return nil } } - return newUnmarshalErrorAfterWithSkipping(dec, uo, t, nil) + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } @@ -199,16 +212,23 @@ func makeStringArshaler(t reflect.Type) *arshaler { var fncs arshaler fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { xe := export.Encoder(enc) - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - return newInvalidFormatError(enc, t, mo) + var stringify bool // always false except `string` tag with StringifyWithLegacySemantics + if mo.Flags.Has(jsonflags.TagFlags) { + stringify = mo.Flags.Get(jsonflags.StringTag) && mo.Flags.Get(jsonflags.StringifyWithLegacySemantics) + if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + } + if mo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(enc, t) + } } // Optimize for marshaling without preceding whitespace. s := va.String() - if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyBoolsAndStrings) && !xe.Tokens.Last.NeedObjectName() { + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify && !xe.Tokens.Last.NeedObjectName() { b := xe.Buf b = xe.Tokens.MayAppendDelim(b, '"') - b, err := jsonwire.AppendQuote(b, s, &mo.Flags) + b, err := jsonwire.AppendQuote(b, []byte(s), &mo.Flags) if err == nil { xe.Buf = b xe.Tokens.Last.Increment() @@ -221,8 +241,8 @@ func makeStringArshaler(t reflect.Type) *arshaler { // so let the logic below construct the proper error. } - if mo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { - b, err := jsonwire.AppendQuote(nil, s, &mo.Flags) + if stringify { + b, err := jsonwire.AppendQuote(nil, []byte(s), &mo.Flags) if err != nil { return newMarshalErrorBefore(enc, t, &jsontext.SyntacticError{Err: err}) } @@ -236,8 +256,15 @@ func makeStringArshaler(t reflect.Type) *arshaler { } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { xd := export.Decoder(dec) - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - return newInvalidFormatError(dec, t, uo) + var stringify bool // always false except `string` tag with StringifyWithLegacySemantics + if uo.Flags.Has(jsonflags.TagFlags) { + stringify = uo.Flags.Get(jsonflags.StringTag) && uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) + if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.StringifyWithLegacySemantics|jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + } + if uo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(dec, t) + } } var flags jsonwire.ValueFlags val, err := xd.ReadValue(&flags) @@ -253,7 +280,7 @@ func makeStringArshaler(t reflect.Type) *arshaler { return nil case '"': val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) - if uo.Flags.Get(jsonflags.StringifyBoolsAndStrings) { + if stringify { val, err = jsontext.AppendUnquote(nil, val) if err != nil { return newUnmarshalErrorAfter(dec, t, err) @@ -311,32 +338,37 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { } xe := export.Encoder(enc) appendEncode := appendEncodeBase64 - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - switch mo.Format { - case "base64": - appendEncode = appendEncodeBase64 - case "base64url": - appendEncode = appendEncodeBase64URL - case "base32": - appendEncode = appendEncodeBase32 - case "base32hex": - appendEncode = appendEncodeBase32Hex - case "base16", "hex": - appendEncode = appendEncodeBase16 - case "array": - mo.Format = "" + if mo.Flags.Has(jsonflags.TagFlags | jsonflags.FormatByteArrayAsArray | jsonflags.FormatBytesWithLegacySemantics | jsonflags.FormatNilSliceAsNull) { + switch { + case mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics): + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + case mo.Flags.Has(jsonflags.FormatTag): + switch mo.Format { + case "base64": + appendEncode = appendEncodeBase64 + case "base64url": + appendEncode = appendEncodeBase64URL + case "base32": + appendEncode = appendEncodeBase32 + case "base32hex": + appendEncode = appendEncodeBase32Hex + case "base16", "hex": + appendEncode = appendEncodeBase16 + case "array": + mo.Flags.Clear(jsonflags.FormatTag) + return marshalArray(enc, va, mo) + default: + return newInvalidFormatError(enc, t) + } + case mo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array: + return marshalArray(enc, va, mo) + case mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && hasMarshaler: return marshalArray(enc, va, mo) - default: - return newInvalidFormatError(enc, t, mo) } - } else if mo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array { - return marshalArray(enc, va, mo) - } else if mo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && hasMarshaler { - return marshalArray(enc, va, mo) - } - if mo.Flags.Get(jsonflags.FormatNilSliceAsNull) && va.Kind() == reflect.Slice && va.IsNil() { - // TODO: Provide a "emitempty" format override? - return enc.WriteToken(jsontext.Null) + if mo.Flags.Get(jsonflags.FormatNilSliceAsNull) && va.Kind() == reflect.Slice && va.IsNil() { + // TODO: Provide an "emitempty" format override? + return enc.WriteToken(jsontext.Null) + } } return xe.AppendRaw('"', true, func(b []byte) ([]byte, error) { return appendEncode(b, va.Bytes()), nil @@ -349,28 +381,33 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { } xd := export.Decoder(dec) appendDecode, encodedLen := appendDecodeBase64, encodedLenBase64 - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - switch uo.Format { - case "base64": - appendDecode, encodedLen = appendDecodeBase64, encodedLenBase64 - case "base64url": - appendDecode, encodedLen = appendDecodeBase64URL, encodedLenBase64URL - case "base32": - appendDecode, encodedLen = appendDecodeBase32, encodedLenBase32 - case "base32hex": - appendDecode, encodedLen = appendDecodeBase32Hex, encodedLenBase32Hex - case "base16", "hex": - appendDecode, encodedLen = appendDecodeBase16, encodedLenBase16 - case "array": - uo.Format = "" + if uo.Flags.Has(jsonflags.TagFlags | jsonflags.FormatByteArrayAsArray | jsonflags.FormatBytesWithLegacySemantics) { + switch { + case uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics): + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + case uo.Flags.Has(jsonflags.FormatTag): + switch uo.Format { + case "base64": + appendDecode, encodedLen = appendDecodeBase64, encodedLenBase64 + case "base64url": + appendDecode, encodedLen = appendDecodeBase64URL, encodedLenBase64URL + case "base32": + appendDecode, encodedLen = appendDecodeBase32, encodedLenBase32 + case "base32hex": + appendDecode, encodedLen = appendDecodeBase32Hex, encodedLenBase32Hex + case "base16", "hex": + appendDecode, encodedLen = appendDecodeBase16, encodedLenBase16 + case "array": + uo.Flags.Clear(jsonflags.FormatTag) + return unmarshalArray(dec, va, uo) + default: + return newInvalidFormatError(dec, t) + } + case uo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array: + return unmarshalArray(dec, va, uo) + case uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && dec.PeekKind() == '[': return unmarshalArray(dec, va, uo) - default: - return newInvalidFormatError(dec, t, uo) } - } else if uo.Flags.Get(jsonflags.FormatByteArrayAsArray) && va.Kind() == reflect.Array { - return unmarshalArray(dec, va, uo) - } else if uo.Flags.Get(jsonflags.FormatBytesWithLegacySemantics) && dec.PeekKind() == '[' { - return unmarshalArray(dec, va, uo) } var flags jsonwire.ValueFlags val, err := xd.ReadValue(&flags) @@ -409,7 +446,7 @@ func makeBytesArshaler(t reflect.Type, fncs *arshaler) *arshaler { if va.Kind() == reflect.Array { dst := va.Bytes() - clear(dst[copy(dst, b):]) // noop if len(b) <= len(dst) + clear(dst[copy(dst, b):]) // noop if len(b) >= len(dst) if len(b) != len(dst) && !uo.Flags.Get(jsonflags.UnmarshalArrayFromAnyLength) { err := fmt.Errorf("decoded length of %d mismatches array length of %d", len(b), len(dst)) return newUnmarshalErrorAfter(dec, t, err) @@ -432,12 +469,13 @@ func makeIntArshaler(t reflect.Type) *arshaler { bits := t.Bits() fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { xe := export.Encoder(enc) - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - return newInvalidFormatError(enc, t, mo) + stringify := xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag) + if mo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(enc, t) } // Optimize for marshaling without preceding whitespace or string escaping. - if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !xe.Tokens.Last.NeedObjectName() { + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify { xe.Buf = strconv.AppendInt(xe.Tokens.MayAppendDelim(xe.Buf, '0'), va.Int(), 10) xe.Tokens.Last.Increment() if xe.NeedFlush() { @@ -446,17 +484,17 @@ func makeIntArshaler(t reflect.Type) *arshaler { return nil } - k := stringOrNumberKind(xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + k := stringOrNumberKind(stringify) return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) { return strconv.AppendInt(b, va.Int(), 10), nil }) } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { xd := export.Decoder(dec) - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - return newInvalidFormatError(dec, t, uo) + stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag) + if uo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(dec, t) } - stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) var flags jsonwire.ValueFlags val, err := xd.ReadValue(&flags) if err != nil { @@ -474,10 +512,21 @@ func makeIntArshaler(t reflect.Type) *arshaler { break } val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) - if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { - if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { - va.SetInt(0) + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + // For historical reasons, v1 parsed a quoted number + // according to the Go syntax and permitted a quoted null. + // See https://go.dev/issue/75619 + n, err := strconv.ParseInt(string(val), 10, bits) + if err != nil { + if string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetInt(0) + } + return nil + } + return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err)) } + va.SetInt(n) return nil } fallthrough @@ -519,12 +568,13 @@ func makeUintArshaler(t reflect.Type) *arshaler { bits := t.Bits() fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { xe := export.Encoder(enc) - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - return newInvalidFormatError(enc, t, mo) + stringify := xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag) + if mo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(enc, t) } // Optimize for marshaling without preceding whitespace or string escaping. - if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !xe.Tokens.Last.NeedObjectName() { + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify { xe.Buf = strconv.AppendUint(xe.Tokens.MayAppendDelim(xe.Buf, '0'), va.Uint(), 10) xe.Tokens.Last.Increment() if xe.NeedFlush() { @@ -533,17 +583,17 @@ func makeUintArshaler(t reflect.Type) *arshaler { return nil } - k := stringOrNumberKind(xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + k := stringOrNumberKind(stringify) return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) { return strconv.AppendUint(b, va.Uint(), 10), nil }) } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { xd := export.Decoder(dec) - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - return newInvalidFormatError(dec, t, uo) + stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag) + if uo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(dec, t) } - stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) var flags jsonwire.ValueFlags val, err := xd.ReadValue(&flags) if err != nil { @@ -561,10 +611,21 @@ func makeUintArshaler(t reflect.Type) *arshaler { break } val = jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) - if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { - if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { - va.SetUint(0) + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + // For historical reasons, v1 parsed a quoted number + // according to the Go syntax and permitted a quoted null. + // See https://go.dev/issue/75619 + n, err := strconv.ParseUint(string(val), 10, bits) + if err != nil { + if string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetUint(0) + } + return nil + } + return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err)) } + va.SetUint(n) return nil } fallthrough @@ -597,12 +658,13 @@ func makeFloatArshaler(t reflect.Type) *arshaler { bits := t.Bits() fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { xe := export.Encoder(enc) + stringify := xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag) var allowNonFinite bool - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + if mo.Flags.Has(jsonflags.FormatTag) { if mo.Format == "nonfinite" { allowNonFinite = true } else { - return newInvalidFormatError(enc, t, mo) + return newInvalidFormatError(enc, t) } } @@ -616,7 +678,7 @@ func makeFloatArshaler(t reflect.Type) *arshaler { } // Optimize for marshaling without preceding whitespace or string escaping. - if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace|jsonflags.StringifyNumbers) && !xe.Tokens.Last.NeedObjectName() { + if optimizeCommon && !mo.Flags.Get(jsonflags.AnyWhitespace) && !stringify { xe.Buf = jsonwire.AppendFloat(xe.Tokens.MayAppendDelim(xe.Buf, '0'), fv, bits) xe.Tokens.Last.Increment() if xe.NeedFlush() { @@ -625,22 +687,23 @@ func makeFloatArshaler(t reflect.Type) *arshaler { return nil } - k := stringOrNumberKind(xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + k := stringOrNumberKind(stringify) return xe.AppendRaw(k, true, func(b []byte) ([]byte, error) { return jsonwire.AppendFloat(b, va.Float(), bits), nil }) } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { xd := export.Decoder(dec) + stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag) var allowNonFinite bool - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + if uo.Flags.Has(jsonflags.FormatTag) { if uo.Format == "nonfinite" { allowNonFinite = true } else { - return newInvalidFormatError(dec, t, uo) + return newInvalidFormatError(dec, t) } } - stringify := xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) + var flags jsonwire.ValueFlags val, err := xd.ReadValue(&flags) if err != nil { @@ -671,10 +734,21 @@ func makeFloatArshaler(t reflect.Type) *arshaler { if !stringify { break } - if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && string(val) == "null" { - if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { - va.SetFloat(0) + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + // For historical reasons, v1 parsed a quoted number + // according to the Go syntax and permitted a quoted null. + // See https://go.dev/issue/75619 + n, err := strconv.ParseFloat(string(val), bits) + if err != nil { + if string(val) == "null" { + if !uo.Flags.Get(jsonflags.MergeWithLegacySemantics) { + va.SetFloat(0) + } + return nil + } + return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err)) } + va.SetFloat(n) return nil } if n, err := jsonwire.ConsumeNumber(val); n != len(val) || err != nil { @@ -685,10 +759,10 @@ func makeFloatArshaler(t reflect.Type) *arshaler { if stringify && k == '0' { break } - fv, ok := jsonwire.ParseFloat(val, bits) + fv, err := strconv.ParseFloat(string(val), bits) va.SetFloat(fv) - if !ok { - return newUnmarshalErrorAfterWithValue(dec, t, strconv.ErrRange) + if err != nil { + return newUnmarshalErrorAfterWithValue(dec, t, errors.Unwrap(err)) } return nil } @@ -728,16 +802,19 @@ func makeMapArshaler(t reflect.Type) *arshaler { } emitNull := mo.Flags.Get(jsonflags.FormatNilMapAsNull) - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - switch mo.Format { - case "emitnull": - emitNull = true - mo.Format = "" - case "emitempty": - emitNull = false - mo.Format = "" - default: - return newInvalidFormatError(enc, t, mo) + if mo.Flags.Has(jsonflags.TagFlags) { + if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + } + if mo.Flags.Has(jsonflags.FormatTag) { + switch mo.Format { + case "emitnull": + emitNull = true + case "emitempty": + emitNull = false + default: + return newInvalidFormatError(enc, t) + } } } @@ -810,7 +887,7 @@ func makeMapArshaler(t reflect.Type) *arshaler { k.SetIterKey(iter) (*names)[i] = k.String() } - names.Sort() + slices.Sort(*names) for _, name := range *names { if err := enc.WriteToken(jsontext.String(name)); err != nil { return err @@ -877,12 +954,16 @@ func makeMapArshaler(t reflect.Type) *arshaler { } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { xd := export.Decoder(dec) - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - switch uo.Format { - case "emitnull", "emitempty": - uo.Format = "" // only relevant for marshaling - default: - return newInvalidFormatError(dec, t, uo) + if uo.Flags.Has(jsonflags.TagFlags) { + if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + } + if uo.Flags.Has(jsonflags.FormatTag) { + switch uo.Format { + case "emitnull", "emitempty": + default: + return newInvalidFormatError(dec, t) + } } } tok, err := dec.ReadToken() @@ -992,7 +1073,7 @@ func makeMapArshaler(t reflect.Type) *arshaler { } return errUnmarshal } - return newUnmarshalErrorAfterWithSkipping(dec, uo, t, nil) + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } @@ -1000,7 +1081,7 @@ func makeMapArshaler(t reflect.Type) *arshaler { // mapKeyWithUniqueRepresentation reports whether all possible values of k // marshal to a different JSON value, and whether all possible JSON values // that can unmarshal into k unmarshal to different Go values. -// In other words, the representation must be a bijective. +// In other words, the representation must be a bijection. func mapKeyWithUniqueRepresentation(k reflect.Kind, allowInvalidUTF8 bool) bool { switch k { case reflect.Bool, @@ -1009,7 +1090,7 @@ func mapKeyWithUniqueRepresentation(k reflect.Kind, allowInvalidUTF8 bool) bool return true case reflect.String: // For strings, we have to be careful since names with invalid UTF-8 - // maybe unescape to the same Go string value. + // may unescape to the same Go string value. return !allowInvalidUTF8 default: // Floating-point kinds are not listed above since NaNs @@ -1019,6 +1100,7 @@ func mapKeyWithUniqueRepresentation(k reflect.Kind, allowInvalidUTF8 bool) bool } var errNilField = errors.New("cannot set embedded pointer to unexported struct type") +var errInvalidStringTag = errors.New("invalid use of `string` tag option") func makeStructArshaler(t reflect.Type) *arshaler { // NOTE: The logic below disables namespaces for tracking duplicate names @@ -1036,13 +1118,21 @@ func makeStructArshaler(t reflect.Type) *arshaler { } fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { xe := export.Encoder(enc) - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - return newInvalidFormatError(enc, t, mo) + if mo.Flags.Has(jsonflags.TagFlags) { + if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + } + if mo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(enc, t) + } } once.Do(init) if errInit != nil && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return newMarshalErrorBefore(enc, errInit.GoType, errInit.Err) + } else if fields.errUnsupportedFormat != nil && !mo.Flags.Get(jsonflags.FormatTagSupported) { + return newMarshalErrorBefore(enc, fields.errUnsupportedFormat.GoType, fields.errUnsupportedFormat.Err) } + if err := enc.WriteToken(jsontext.BeginObject); err != nil { return err } @@ -1055,7 +1145,7 @@ func makeStructArshaler(t reflect.Type) *arshaler { if len(f.index) > 0 { v = v.fieldByIndex(f.index, false) if !v.IsValid() { - continue // implies a nil inlined field + continue // implies a nil embedded field } } @@ -1115,7 +1205,7 @@ func makeStructArshaler(t reflect.Type) *arshaler { if !f.nameNeedEscape { b = append(b, f.quotedName...) } else { - b, _ = jsonwire.AppendQuote(b, f.name, &mo.Flags) + b, _ = jsonwire.AppendQuote(b, []byte(f.name), &mo.Flags) } xe.Buf = b xe.Names.ReplaceLastQuotedOffset(n0) @@ -1129,14 +1219,10 @@ func makeStructArshaler(t reflect.Type) *arshaler { // Write the object member value. flagsOriginal := mo.Flags if f.string { - if !mo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { - mo.Flags.Set(jsonflags.StringifyNumbers | 1) - } else if canLegacyStringify(f.typ) { - mo.Flags.Set(jsonflags.StringifyNumbers | jsonflags.StringifyBoolsAndStrings | 1) - } + mo.Flags.Set(jsonflags.StringTag | 1) } if f.format != "" { - mo.FormatDepth = xe.Tokens.Depth() + mo.Flags.Set(jsonflags.FormatTag | 1) mo.Format = f.format } err := marshal(enc, v, mo) @@ -1159,17 +1245,17 @@ func makeStructArshaler(t reflect.Type) *arshaler { // Remember the previous written object member. // The set of seen fields only needs to be updated to detect - // duplicate names with those from the inlined fallback. - if !mo.Flags.Get(jsonflags.AllowDuplicateNames) && fields.inlinedFallback != nil { + // duplicate names with those from the embedded fallback. + if !mo.Flags.Get(jsonflags.AllowDuplicateNames) && fields.embeddedFallback != nil { seenIdxs.insert(uint(f.id)) } prevIdx = f.id } - if fields.inlinedFallback != nil && !(mo.Flags.Get(jsonflags.DiscardUnknownMembers) && fields.inlinedFallback.unknown) { + if fields.embeddedFallback != nil { var insertUnquotedName func([]byte) bool if !mo.Flags.Get(jsonflags.AllowDuplicateNames) { insertUnquotedName = func(name []byte) bool { - // Check that the name from inlined fallback does not match + // Check that the name from embedded fallback does not match // one of the previously marshaled names from known fields. if foldedFields := fields.lookupByFoldedName(name); len(foldedFields) > 0 { if f := fields.byActualName[string(name)]; f != nil { @@ -1183,11 +1269,11 @@ func makeStructArshaler(t reflect.Type) *arshaler { } // Check that the name does not match any other name - // previously marshaled from the inlined fallback. + // previously marshaled from the embedded fallback. return xe.Namespaces.Last().InsertUnquoted(name) } } - if err := marshalInlinedFallbackAll(enc, va, mo, fields.inlinedFallback, insertUnquotedName); err != nil { + if err := marshalEmbeddedFallbackAll(enc, va, mo, fields.embeddedFallback, insertUnquotedName); err != nil { return err } } @@ -1198,8 +1284,13 @@ func makeStructArshaler(t reflect.Type) *arshaler { } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { xd := export.Decoder(dec) - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - return newInvalidFormatError(dec, t, uo) + if uo.Flags.Has(jsonflags.TagFlags) { + if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + } + if uo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(dec, t) + } } tok, err := dec.ReadToken() if err != nil { @@ -1216,7 +1307,10 @@ func makeStructArshaler(t reflect.Type) *arshaler { once.Do(init) if errInit != nil && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return newUnmarshalErrorAfter(dec, errInit.GoType, errInit.Err) + } else if fields.errUnsupportedFormat != nil && !uo.Flags.Get(jsonflags.FormatTagSupported) { + return newUnmarshalErrorAfter(dec, fields.errUnsupportedFormat.GoType, fields.errUnsupportedFormat.Err) } + var seenIdxs uintSet xd.Tokens.Last.DisableNamespace() var errUnmarshal error @@ -1230,14 +1324,20 @@ func makeStructArshaler(t reflect.Type) *arshaler { name := jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) f := fields.byActualName[string(name)] if f == nil { + var numMatch int for _, f2 := range fields.lookupByFoldedName(name) { if f2.matchFoldedName(name, &uo.Flags) { - f = f2 - break + if f == nil { + f = f2 // use first seen name by breadth-first order + } + numMatch++ } } + if numMatch > 1 && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorAfter(dec, t, errAmbiguousName) + } if f == nil { - if uo.Flags.Get(jsonflags.RejectUnknownMembers) && (fields.inlinedFallback == nil || fields.inlinedFallback.unknown) { + if uo.Flags.Get(jsonflags.RejectUnknownMembers) && fields.embeddedFallback == nil { err := newUnmarshalErrorAfter(dec, t, ErrUnknownName) if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return err @@ -1249,14 +1349,14 @@ func makeStructArshaler(t reflect.Type) *arshaler { return newDuplicateNameError(dec.StackPointer(), nil, dec.InputOffset()-len64(val)) } - if fields.inlinedFallback == nil { + if fields.embeddedFallback == nil { // Skip unknown value since we have no place to store it. if err := dec.SkipValue(); err != nil { return err } } else { - // Marshal into value capable of storing arbitrary object members. - if err := unmarshalInlinedFallbackNext(dec, va, uo, fields.inlinedFallback, val, name); err != nil { + // Unmarshal into a value capable of storing arbitrary object members. + if err := unmarshalEmbeddedFallbackNext(dec, va, uo, fields.embeddedFallback, val, name); err != nil { if isFatalError(err, uo.Flags) { return err } @@ -1278,14 +1378,10 @@ func makeStructArshaler(t reflect.Type) *arshaler { } flagsOriginal := uo.Flags if f.string { - if !uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { - uo.Flags.Set(jsonflags.StringifyNumbers | 1) - } else if canLegacyStringify(f.typ) { - uo.Flags.Set(jsonflags.StringifyNumbers | jsonflags.StringifyBoolsAndStrings | 1) - } + uo.Flags.Set(jsonflags.StringTag | 1) } if f.format != "" { - uo.FormatDepth = xd.Tokens.Depth() + uo.Flags.Set(jsonflags.FormatTag | 1) uo.Format = f.format } v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable @@ -1317,7 +1413,7 @@ func makeStructArshaler(t reflect.Type) *arshaler { } return errUnmarshal } - return newUnmarshalErrorAfterWithSkipping(dec, uo, t, nil) + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } @@ -1366,25 +1462,6 @@ func isLegacyEmpty(v addressableValue) bool { return false } -// canLegacyStringify reports whether t can be stringified according to v1, -// where t is a bool, string, or number (or unnamed pointer to such). -// In v1, the `string` option does not apply recursively to nested types within -// a composite Go type (e.g., an array, slice, struct, map, or interface). -func canLegacyStringify(t reflect.Type) bool { - // Based on encoding/json.typeFields#L1126-L1143@v1.23.0 - if t.Name() == "" && t.Kind() == reflect.Ptr { - t = t.Elem() - } - switch t.Kind() { - case reflect.Bool, reflect.String, - reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, - reflect.Float32, reflect.Float64: - return true - } - return false -} - func makeSliceArshaler(t reflect.Type) *arshaler { var fncs arshaler var ( @@ -1405,16 +1482,19 @@ func makeSliceArshaler(t reflect.Type) *arshaler { } emitNull := mo.Flags.Get(jsonflags.FormatNilSliceAsNull) - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - switch mo.Format { - case "emitnull": - emitNull = true - mo.Format = "" - case "emitempty": - emitNull = false - mo.Format = "" - default: - return newInvalidFormatError(enc, t, mo) + if mo.Flags.Has(jsonflags.TagFlags) { + if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + } + if mo.Flags.Has(jsonflags.FormatTag) { + switch mo.Format { + case "emitnull": + emitNull = true + case "emitempty": + emitNull = false + default: + return newInvalidFormatError(enc, t) + } } } @@ -1456,13 +1536,16 @@ func makeSliceArshaler(t reflect.Type) *arshaler { } emptySlice := reflect.MakeSlice(t, 0, 0) fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { - xd := export.Decoder(dec) - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - switch uo.Format { - case "emitnull", "emitempty": - uo.Format = "" // only relevant for marshaling - default: - return newInvalidFormatError(dec, t, uo) + if uo.Flags.Has(jsonflags.TagFlags) { + if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + } + if uo.Flags.Has(jsonflags.FormatTag) { + switch uo.Format { + case "emitnull", "emitempty": + default: + return newInvalidFormatError(dec, t) + } } } @@ -1518,7 +1601,7 @@ func makeSliceArshaler(t reflect.Type) *arshaler { } return errUnmarshal } - return newUnmarshalErrorAfterWithSkipping(dec, uo, t, nil) + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } @@ -1537,9 +1620,13 @@ func makeArrayArshaler(t reflect.Type) *arshaler { } n := t.Len() fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { - xe := export.Encoder(enc) - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - return newInvalidFormatError(enc, t, mo) + if mo.Flags.Has(jsonflags.TagFlags) { + if mo.Flags.Get(jsonflags.StringTag) && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + } + if mo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(enc, t) + } } once.Do(init) if err := enc.WriteToken(jsontext.BeginArray); err != nil { @@ -1561,9 +1648,13 @@ func makeArrayArshaler(t reflect.Type) *arshaler { return nil } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { - xd := export.Decoder(dec) - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - return newInvalidFormatError(dec, t, uo) + if uo.Flags.Has(jsonflags.TagFlags) { + if uo.Flags.Get(jsonflags.StringTag) && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + } + if uo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(dec, t) + } } tok, err := dec.ReadToken() if err != nil { @@ -1616,7 +1707,7 @@ func makeArrayArshaler(t reflect.Type) *arshaler { } return errUnmarshal } - return newUnmarshalErrorAfterWithSkipping(dec, uo, t, nil) + return newUnmarshalErrorAfterWithSkipping(dec, t, nil) } return &fncs } @@ -1641,6 +1732,12 @@ func makePointerArshaler(t reflect.Type) *arshaler { } // NOTE: Struct.Format is forwarded to underlying marshal. + if mo.Flags.Get(jsonflags.StringTag) && mo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && t.Elem().Kind() == reflect.Pointer { + if !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + } + mo.Flags.Clear(jsonflags.StringTag) // the `string` tag option does not apply to nested pointers + } if va.IsNil() { return enc.WriteToken(jsontext.Null) } @@ -1661,6 +1758,12 @@ func makePointerArshaler(t reflect.Type) *arshaler { va.SetZero() return nil } + if uo.Flags.Get(jsonflags.StringTag) && uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && t.Elem().Kind() == reflect.Pointer { + if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + } + uo.Flags.Clear(jsonflags.StringTag) // the `string` tag option does not apply to nested pointers + } once.Do(init) unmarshal := valFncs.unmarshal if uo.Unmarshalers != nil { @@ -1673,8 +1776,7 @@ func makePointerArshaler(t reflect.Type) *arshaler { if err := unmarshal(dec, v, uo); err != nil { return err } - if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) && - uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringifyBoolsAndStrings) { + if uo.Flags.Get(jsonflags.StringTag) && uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { // A JSON null quoted within a JSON string should take effect // within the pointer value, rather than the indirect value. // @@ -1704,9 +1806,18 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { } } fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { - xe := export.Encoder(enc) - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { - return newInvalidFormatError(enc, t, mo) + if mo.Flags.Has(jsonflags.TagFlags) { + if mo.Flags.Get(jsonflags.StringTag) { + if !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + } + if mo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + mo.Flags.Clear(jsonflags.StringTag) // the `string` tag option does not apply to interface types + } + } + if mo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(enc, t) + } } if va.IsNil() { return enc.WriteToken(jsontext.Null) @@ -1737,16 +1848,25 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { } // Optimize for the any type if there are no special options. if optimizeCommon && - t == anyType && !mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringifyBoolsAndStrings) && mo.Format == "" && + t == anyType && !mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.TagFlags) && (mo.Marshalers == nil || !mo.Marshalers.(*Marshalers).fromAny) { return marshalValueAny(enc, va.Elem().Interface(), mo) } return marshal(enc, v, mo) } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { - xd := export.Decoder(dec) - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { - return newInvalidFormatError(dec, t, uo) + if uo.Flags.Has(jsonflags.TagFlags) { + if uo.Flags.Get(jsonflags.StringTag) { + if !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + } + if uo.Flags.Get(jsonflags.StringifyWithLegacySemantics) { + uo.Flags.Clear(jsonflags.StringTag) // the `string` tag option does not apply to interface types + } + } + if uo.Flags.Has(jsonflags.FormatTag) { + return newInvalidFormatError(dec, t) + } } if uo.Flags.Get(jsonflags.MergeWithLegacySemantics) && !va.IsNil() { // Legacy merge behavior is difficult to explain. @@ -1782,7 +1902,7 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { // Duplicate name check must be enforced since unmarshalValueAny // does not implement merge semantics. if optimizeCommon && - t == anyType && !uo.Flags.Get(jsonflags.AllowDuplicateNames) && uo.Format == "" && + t == anyType && !uo.Flags.Get(jsonflags.AllowDuplicateNames|jsonflags.FormatTag) && (uo.Unmarshalers == nil || !uo.Unmarshalers.(*Unmarshalers).fromAny) { v, err := unmarshalValueAny(dec, uo) // We must check for nil interface values up front. @@ -1795,7 +1915,7 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { k := dec.PeekKind() if !isAnyType(t) { - return newUnmarshalErrorBeforeWithSkipping(dec, uo, t, internal.ErrNilInterface) + return newUnmarshalErrorBeforeWithSkipping(dec, t, internal.ErrNilInterface) } switch k { case 'f', 't': @@ -1838,7 +1958,7 @@ func makeInterfaceArshaler(t reflect.Type) *arshaler { return &fncs } -// isAnyType reports wether t is equivalent to the any interface type. +// isAnyType reports whether t is equivalent to the any interface type. func isAnyType(t reflect.Type) bool { // This is forward compatible if the Go language permits type sets within // ordinary interfaces where an interface with zero methods does not @@ -1853,6 +1973,19 @@ func makeInvalidArshaler(t reflect.Type) *arshaler { return newMarshalErrorBefore(enc, t, nil) } fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { + // Under legacy error semantics, unmarshal continues on even with errors. + // Thus, always consume the value first. + // As a special-case, null is permitted for unsupported types. + if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + switch val, err := dec.ReadValue(); { + case err != nil: + return err + case val.Kind() == 'n': + return nil + default: + return newUnmarshalErrorAfter(dec, t, nil) + } + } return newUnmarshalErrorBefore(dec, t, nil) } return &fncs diff --git a/vendor/github.com/go-json-experiment/json/arshal_inlined.go b/vendor/github.com/go-json-experiment/json/arshal_embedded.go similarity index 80% rename from vendor/github.com/go-json-experiment/json/arshal_inlined.go rename to vendor/github.com/go-json-experiment/json/arshal_embedded.go index 6a4ab6f..2f190ae 100644 --- a/vendor/github.com/go-json-experiment/json/arshal_inlined.go +++ b/vendor/github.com/go-json-experiment/json/arshal_embedded.go @@ -11,6 +11,7 @@ import ( "errors" "io" "reflect" + "slices" "github.com/go-json-experiment/json/internal/jsonflags" "github.com/go-json-experiment/json/internal/jsonopts" @@ -18,30 +19,30 @@ import ( "github.com/go-json-experiment/json/jsontext" ) -// This package supports "inlining" a Go struct field, where the contents +// This package supports "embedding" a Go struct field, where the contents // of the serialized field (which must be a JSON object) are treated as if // they are part of the parent Go struct (which represents a JSON object). // -// Generally, inlined fields are of a Go struct type, where the fields of the +// Generally, embedded fields are of a Go struct type, where the fields of the // nested struct are virtually hoisted up to the parent struct using rules // similar to how Go embedding works (but operating within the JSON namespace). // -// However, inlined fields may also be of a Go map type with a string key or -// a jsontext.Value. Such inlined fields are called "fallback" fields since they +// However, embedded fields may also be of a Go map type with a string key or +// a jsontext.Value. Such embedded fields are called "fallback" fields since they // represent any arbitrary JSON object member. Explicitly named fields take -// precedence over the inlined fallback. Only one inlined fallback is allowed. +// precedence over the embedded fallback. Only one embedded fallback is allowed. -var errRawInlinedNotObject = errors.New("inlined raw value must be a JSON object") +var errRawEmbedNotObject = errors.New("embedded raw value must be a JSON object") var jsontextValueType = reflect.TypeFor[jsontext.Value]() -// marshalInlinedFallbackAll marshals all the members in an inlined fallback. -func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct, f *structField, insertUnquotedName func([]byte) bool) error { +// marshalEmbeddedFallbackAll marshals all the members in an embedded fallback. +func marshalEmbeddedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct, f *structField, insertUnquotedName func([]byte) bool) error { v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable if len(f.index) > 0 { v = v.fieldByIndex(f.index, false) if !v.IsValid() { - return nil // implies a nil inlined field + return nil // implies a nil embedded field } } v = v.indirect(false) @@ -50,8 +51,7 @@ func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *j } if v.Type() == jsontextValueType { - // TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo. - b := *v.Addr().Interface().(*jsontext.Value) + b, _ := reflect.TypeAssert[jsontext.Value](v.Value) if len(b) == 0 { // TODO: Should this be nil? What if it were all whitespace? return nil } @@ -69,7 +69,7 @@ func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *j return newMarshalErrorBefore(enc, v.Type(), err) } if tok.Kind() != '{' { - return newMarshalErrorBefore(enc, v.Type(), errRawInlinedNotObject) + return newMarshalErrorBefore(enc, v.Type(), errRawEmbedNotObject) } for dec.PeekKind() != '}' { // Parse the JSON object name. @@ -113,7 +113,7 @@ func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *j mk := newAddressableValue(m.Type().Key()) mv := newAddressableValue(m.Type().Elem()) marshalKey := func(mk addressableValue) error { - b, err := jsonwire.AppendQuote(enc.AvailableBuffer(), mk.String(), &mo.Flags) + b, err := jsonwire.AppendQuote(enc.AvailableBuffer(), []byte(mk.String()), &mo.Flags) if err != nil { return newMarshalErrorBefore(enc, m.Type().Key(), err) } @@ -147,7 +147,7 @@ func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *j mk.SetIterKey(iter) (*names)[i] = mk.String() } - names.Sort() + slices.Sort(*names) for _, name := range *names { mk.SetString(name) if err := marshalKey(mk); err != nil { @@ -165,8 +165,8 @@ func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *j } } -// unmarshalInlinedFallbackNext unmarshals only the next member in an inlined fallback. -func unmarshalInlinedFallbackNext(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct, f *structField, quotedName, unquotedName []byte) error { +// unmarshalEmbeddedFallbackNext unmarshals only the next member in an embedded fallback. +func unmarshalEmbeddedFallbackNext(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct, f *structField, quotedName, unquotedName []byte) error { v := addressableValue{va.Field(f.index0), va.forcedAddr} // addressable if struct value is addressable if len(f.index) > 0 { v = v.fieldByIndex(f.index, true) @@ -174,7 +174,7 @@ func unmarshalInlinedFallbackNext(dec *jsontext.Decoder, va addressableValue, uo v = v.indirect(true) if v.Type() == jsontextValueType { - b := v.Addr().Interface().(*jsontext.Value) + b, _ := reflect.TypeAssert[*jsontext.Value](v.Addr()) if len(*b) == 0 { // TODO: Should this be nil? What if it were all whitespace? *b = append(*b, '{') } else { @@ -188,7 +188,7 @@ func unmarshalInlinedFallbackNext(dec *jsontext.Decoder, va addressableValue, uo *b = append(*b, ',') } } else { - return newUnmarshalErrorAfterWithSkipping(dec, uo, v.Type(), errRawInlinedNotObject) + return newUnmarshalErrorAfterWithSkipping(dec, v.Type(), errRawEmbedNotObject) } } *b = append(*b, quotedName...) diff --git a/vendor/github.com/go-json-experiment/json/arshal_funcs.go b/vendor/github.com/go-json-experiment/json/arshal_funcs.go index dd94ac5..63c464d 100644 --- a/vendor/github.com/go-json-experiment/json/arshal_funcs.go +++ b/vendor/github.com/go-json-experiment/json/arshal_funcs.go @@ -9,6 +9,7 @@ package json import ( "errors" "fmt" + "io" "reflect" "sync" @@ -18,16 +19,7 @@ import ( "github.com/go-json-experiment/json/jsontext" ) -// SkipFunc may be returned by [MarshalToFunc] and [UnmarshalFromFunc] functions. -// -// Any function that returns SkipFunc must not cause observable side effects -// on the provided [jsontext.Encoder] or [jsontext.Decoder]. -// For example, it is permissible to call [jsontext.Decoder.PeekKind], -// but not permissible to call [jsontext.Decoder.ReadToken] or -// [jsontext.Encoder.WriteToken] since such methods mutate the state. -var SkipFunc = errors.New("json: skip function") - -var errSkipMutation = errors.New("must not read or write any tokens when skipping") +var errUnsupportedMutation = errors.New("unsupported calls must not read or write any tokens") var errNonSingularValue = errors.New("must read or write exactly one value") // Marshalers is a list of functions that may override the marshal behavior @@ -40,7 +32,8 @@ type Marshalers = typedMarshalers // JoinMarshalers constructs a flattened list of marshal functions. // If multiple functions in the list are applicable for a value of a given type, // then those earlier in the list take precedence over those that come later. -// If a function returns [SkipFunc], then the next applicable function is called, +// If a function returns [errors.ErrUnsupported], +// then the next applicable function is called, // otherwise the default marshaling behavior is used. // // For example: @@ -62,7 +55,8 @@ type Unmarshalers = typedUnmarshalers // JoinUnmarshalers constructs a flattened list of unmarshal functions. // If multiple functions in the list are applicable for a value of a given type, // then those earlier in the list take precedence over those that come later. -// If a function returns [SkipFunc], then the next applicable function is called, +// If a function returns [errors.ErrUnsupported], +// then the next applicable function is called, // otherwise the default unmarshaling behavior is used. // // For example: @@ -150,7 +144,7 @@ func (a *typedArshalers[Coder]) lookup(fnc func(*Coder, addressableValue, *jsono fncDefault := fnc fnc = func(c *Coder, v addressableValue, o *jsonopts.Struct) error { for _, fnc := range fncs { - if err := fnc(c, v, o); err != SkipFunc { + if err := fnc(c, v, o); !errors.Is(err, errors.ErrUnsupported) { return err // may be nil or non-nil } } @@ -168,18 +162,19 @@ func (a *typedArshalers[Coder]) lookup(fnc func(*Coder, addressableValue, *jsono // The function is always provided with a non-nil pointer value // if T is an interface or pointer type. // -// The function must marshal exactly one JSON value. -// The value of T must not be retained outside the function call. -// It may not return [SkipFunc]. +// Implementations must follow the requirements of [Marshaler]. +// +// Implementations must not retain the value of T. func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers { t := reflect.TypeFor[T]() assertCastableTo(t, true) typFnc := typedMarshaler{ typ: t, fnc: func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { - val, err := fn(va.castTo(t).Interface().(T)) + v, _ := reflect.TypeAssert[T](va.castTo(t)) + val, err := fn(v) if err != nil { - err = wrapSkipFunc(err, "marshal function of type func(T) ([]byte, error)") + err = wrapErrUnsupported(err, "marshal function of type func(T) ([]byte, error)") if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalFunc") // unlike unmarshal, always wrapped } @@ -207,12 +202,10 @@ func MarshalFunc[T any](fn func(T) ([]byte, error)) *Marshalers { // The function is always provided with a non-nil pointer value // if T is an interface or pointer type. // -// The function must marshal exactly one JSON value by calling write methods -// on the provided encoder. It may return [SkipFunc] such that marshaling can -// move on to the next marshal function. However, no mutable method calls may -// be called on the encoder if [SkipFunc] is returned. -// The pointer to [jsontext.Encoder] and the value of T -// must not be retained outside the function call. +// Implementations must follow the requirements of [MarshalerTo]. +// +// Implementations must not retain the pointer to [jsontext.Encoder] or the +// value of T. func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers { t := reflect.TypeFor[T]() assertCastableTo(t, true) @@ -222,18 +215,19 @@ func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers { xe := export.Encoder(enc) prevDepth, prevLength := xe.Tokens.DepthLength() xe.Flags.Set(jsonflags.WithinArshalCall | 1) - err := fn(enc, va.castTo(t).Interface().(T)) + v, _ := reflect.TypeAssert[T](va.castTo(t)) + err := fn(enc, v) xe.Flags.Set(jsonflags.WithinArshalCall | 0) currDepth, currLength := xe.Tokens.DepthLength() if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) { err = errNonSingularValue } if err != nil { - if err == SkipFunc { + if errors.Is(err, errors.ErrUnsupported) { if prevDepth == currDepth && prevLength == currLength { - return SkipFunc + return err // forward [errors.ErrUnsupported] } - err = errSkipMutation + err = errUnsupportedMutation } if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalToFunc") // unlike unmarshal, always wrapped @@ -255,10 +249,9 @@ func MarshalToFunc[T any](fn func(*jsontext.Encoder, T) error) *Marshalers { // T must be an unnamed pointer or an interface type. // The function is always provided with a non-nil pointer value. // -// The function must unmarshal exactly one JSON value. -// The input []byte must not be mutated. -// The input []byte and value T must not be retained outside the function call. -// It may not return [SkipFunc]. +// Implementations must follow the requirements of [Unmarshaler]. +// +// Implementations must not retain the value of T. func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers { t := reflect.TypeFor[T]() assertCastableTo(t, false) @@ -269,9 +262,10 @@ func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers { if err != nil { return err // must be a syntactic or I/O error } - err = fn(val, va.castTo(t).Interface().(T)) + v, _ := reflect.TypeAssert[T](va.castTo(t)) + err = fn(val, v) if err != nil { - err = wrapSkipFunc(err, "unmarshal function of type func([]byte, T) error") + err = wrapErrUnsupported(err, "unmarshal function of type func([]byte, T) error") if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return err // unlike marshal, never wrapped } @@ -289,12 +283,10 @@ func UnmarshalFunc[T any](fn func([]byte, T) error) *Unmarshalers { // T must be an unnamed pointer or an interface type. // The function is always provided with a non-nil pointer value. // -// The function must unmarshal exactly one JSON value by calling read methods -// on the provided decoder. It may return [SkipFunc] such that unmarshaling can -// move on to the next unmarshal function. However, no mutable method calls may -// be called on the decoder if [SkipFunc] is returned. -// The pointer to [jsontext.Decoder] and the value of T -// must not be retained outside the function call. +// Implementations must follow the requirements of [UnmarshalerFrom]. +// +// Implementations must not retain the pointer to [jsontext.Decoder] or the +// value of T. func UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers { t := reflect.TypeFor[T]() assertCastableTo(t, false) @@ -303,19 +295,23 @@ func UnmarshalFromFunc[T any](fn func(*jsontext.Decoder, T) error) *Unmarshalers fnc: func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { xd := export.Decoder(dec) prevDepth, prevLength := xd.Tokens.DepthLength() + if prevDepth == 1 && xd.AtEOF() { + return io.EOF // check EOF early to avoid fn reporting an EOF + } xd.Flags.Set(jsonflags.WithinArshalCall | 1) - err := fn(dec, va.castTo(t).Interface().(T)) + v, _ := reflect.TypeAssert[T](va.castTo(t)) + err := fn(dec, v) xd.Flags.Set(jsonflags.WithinArshalCall | 0) currDepth, currLength := xd.Tokens.DepthLength() if err == nil && (prevDepth != currDepth || prevLength+1 != currLength) { err = errNonSingularValue } if err != nil { - if err == SkipFunc { + if errors.Is(err, errors.ErrUnsupported) { if prevDepth == currDepth && prevLength == currLength { - return SkipFunc + return err // forward [errors.ErrUnsupported] } - err = errSkipMutation + err = errUnsupportedMutation } if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { if err2 := xd.SkipUntil(prevDepth, prevLength+1); err2 != nil { @@ -423,10 +419,3 @@ func castableToFromAny(to reflect.Type) bool { } return false } - -func wrapSkipFunc(err error, what string) error { - if err == SkipFunc { - return errors.New(what + " cannot be skipped") - } - return err -} diff --git a/vendor/github.com/go-json-experiment/json/arshal_methods.go b/vendor/github.com/go-json-experiment/json/arshal_methods.go index 82f515e..6b39261 100644 --- a/vendor/github.com/go-json-experiment/json/arshal_methods.go +++ b/vendor/github.com/go-json-experiment/json/arshal_methods.go @@ -9,6 +9,7 @@ package json import ( "encoding" "errors" + "io" "reflect" "github.com/go-json-experiment/json/internal" @@ -37,62 +38,131 @@ var ( // Marshaler is implemented by types that can marshal themselves. // It is recommended that types implement [MarshalerTo] unless the implementation -// is trying to avoid a hard dependency on the "jsontext" package. +// is trying to avoid directly depending on the "jsontext" package. // -// It is recommended that implementations return a buffer that is safe +// Implementations should return a buffer that is safe // for the caller to retain and potentially mutate. +// +// Implementations must not return [errors.ErrUnsupported]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError]. +// +// Implementations should assume [Deterministic] is true and return +// deterministic output. type Marshaler interface { MarshalJSON() ([]byte, error) } // MarshalerTo is implemented by types that can marshal themselves. // It is recommended that types implement MarshalerTo instead of [Marshaler] -// since this is both more performant and flexible. +// since it is both more performant and more flexible. // If a type implements both Marshaler and MarshalerTo, // then MarshalerTo takes precedence. In such a case, both implementations // should aim to have equivalent behavior for the default marshal options. // -// The implementation must write only one JSON value to the Encoder and -// must not retain the pointer to [jsontext.Encoder]. +// The implementation must write only one JSON value to the Encoder. +// Alternatively, it may return [errors.ErrUnsupported] without mutating +// the Encoder. The "json" package calling the method will +// use the next available JSON representation for the receiver type, +// as described in [Marshal]. +// Implementations must not retain the pointer to [jsontext.Encoder]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError], +// except for IO errors. +// +// The MarshalJSONTo method should not be called directly as it may +// return sentinel errors that need special handling. +// Users should instead call [MarshalEncode], which handles such cases. +// +// Implementations should inspect the marshal options from +// [jsontext.Encoder.Options] and adjust behavior to respect the options as +// necessary. +// +// The following options may be relevant to MarshalerTo implementations: +// +// - [Deterministic]: if the implementation may produce non-deterministic output +// - [StringifyNumbers]: if the type is represented as a JSON number +// +// Several options, such as [FormatNilSliceAsNull], apply only to native Go +// types. Thus, these options are typically not directly relevant to +// MarshalerTo implementations. However, types representing a composite type +// should marshal contained types using [MarshalEncode] to ensure these options +// apply to the contained types. Similarly, [WithMarshalers] may influence +// marshaling of any contained type within a composite type. +// +// All other options are automatically handled outside of the MarshalerTo +// implementation, and thus are not relevant to implementations. type MarshalerTo interface { MarshalJSONTo(*jsontext.Encoder) error - - // TODO: Should users call the MarshalEncode function or - // should/can they call this method directly? Does it matter? } // Unmarshaler is implemented by types that can unmarshal themselves. // It is recommended that types implement [UnmarshalerFrom] unless the implementation -// is trying to avoid a hard dependency on the "jsontext" package. +// is trying to avoid a direct dependency on the "jsontext" package. // // The input can be assumed to be a valid encoding of a JSON value // if called from unmarshal functionality in this package. -// UnmarshalJSON must copy the JSON data if it is retained after returning. -// It is recommended that UnmarshalJSON implement merge semantics when -// unmarshaling into a pre-populated value. +// It is recommended that UnmarshalJSON implement merge semantics +// when unmarshaling into a pre-populated value, as described in [Unmarshal]. // // Implementations must not retain or mutate the input []byte. +// +// Implementations must not return [errors.ErrUnsupported]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError]. type Unmarshaler interface { UnmarshalJSON([]byte) error } // UnmarshalerFrom is implemented by types that can unmarshal themselves. // It is recommended that types implement UnmarshalerFrom instead of [Unmarshaler] -// since this is both more performant and flexible. +// since this is both more performant and more flexible. // If a type implements both Unmarshaler and UnmarshalerFrom, // then UnmarshalerFrom takes precedence. In such a case, both implementations // should aim to have equivalent behavior for the default unmarshal options. // // The implementation must read only one JSON value from the Decoder. // It is recommended that UnmarshalJSONFrom implement merge semantics when -// unmarshaling into a pre-populated value. -// +// unmarshaling into a pre-populated value, as described in [Unmarshal]. +// Alternatively, it may return [errors.ErrUnsupported] without mutating +// the Decoder. The "json" package calling the method will +// use the next available JSON representation for the receiver type. // Implementations must not retain the pointer to [jsontext.Decoder]. +// +// If the returned error is a [SemanticError], then unpopulated fields +// of the error may be populated by [json] with additional context. +// Errors of other types are wrapped within a [SemanticError], +// except for [jsontext.SyntacticError]s and IO errors. +// +// The UnmarshalJSONFrom method should not be called directly as it may +// return sentinel errors that need special handling. +// Users should instead call [UnmarshalDecode], which handles such cases. +// +// Implementations should inspect the unmarshal options from +// [jsontext.Decoder.Options] and adjust behavior to respect the options as +// necessary. +// +// The following options may be relevant to UnmarshalerFrom implementations: +// +// - [StringifyNumbers]: if the type is represented as a JSON number +// +// Several options, such as [FormatNilSliceAsNull], apply only to native Go +// types. Thus, these options are typically not directly relevant to +// UnmarshalerFrom implementations. However, types representing a composite +// type should unmarshal contained types using [UnmarshalDecode] to ensure +// these options apply to the contained types. Similarly, [WithUnmarshalers] +// may influence unmarshaling of any contained type within a composite type. +// +// All other options are automatically handled outside of the UnmarshalerFrom +// implementation, and thus are not relevant to implementations. type UnmarshalerFrom interface { UnmarshalJSONFrom(*jsontext.Decoder) error - - // TODO: Should users call the UnmarshalDecode function or - // should/can they call this method directly? Does it matter? } func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { @@ -111,12 +181,12 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { (needAddr && va.forcedAddr) { return prevMarshal(enc, va, mo) } - marshaler := va.Addr().Interface().(encoding.TextMarshaler) + marshaler, _ := reflect.TypeAssert[encoding.TextMarshaler](va.Addr()) if err := export.Encoder(enc).AppendRaw('"', false, func(b []byte) ([]byte, error) { b2, err := marshaler.MarshalText() return append(b, b2...), err }); err != nil { - err = wrapSkipFunc(err, "marshal method") + err = wrapErrUnsupported(err, "MarshalText method") if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalText") // unlike unmarshal, always wrapped } @@ -137,9 +207,9 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { (needAddr && va.forcedAddr) { return prevMarshal(enc, va, mo) } - appender := va.Addr().Interface().(encoding.TextAppender) + appender, _ := reflect.TypeAssert[encoding.TextAppender](va.Addr()) if err := export.Encoder(enc).AppendRaw('"', false, appender.AppendText); err != nil { - err = wrapSkipFunc(err, "append method") + err = wrapErrUnsupported(err, "AppendText method") if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return internal.NewMarshalerError(va.Addr().Interface(), err, "AppendText") // unlike unmarshal, always wrapped } @@ -160,10 +230,10 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { ((needAddr && va.forcedAddr) || export.Encoder(enc).Tokens.Last.NeedObjectName()) { return prevMarshal(enc, va, mo) } - marshaler := va.Addr().Interface().(Marshaler) + marshaler, _ := reflect.TypeAssert[Marshaler](va.Addr()) val, err := marshaler.MarshalJSON() if err != nil { - err = wrapSkipFunc(err, "marshal method") + err = wrapErrUnsupported(err, "MarshalJSON method") if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalJSON") // unlike unmarshal, always wrapped } @@ -194,14 +264,20 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { xe := export.Encoder(enc) prevDepth, prevLength := xe.Tokens.DepthLength() xe.Flags.Set(jsonflags.WithinArshalCall | 1) - err := va.Addr().Interface().(MarshalerTo).MarshalJSONTo(enc) + marshaler, _ := reflect.TypeAssert[MarshalerTo](va.Addr()) + err := marshaler.MarshalJSONTo(enc) xe.Flags.Set(jsonflags.WithinArshalCall | 0) currDepth, currLength := xe.Tokens.DepthLength() if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil { err = errNonSingularValue } if err != nil { - err = wrapSkipFunc(err, "marshal method") + if errors.Is(err, errors.ErrUnsupported) { + if prevDepth == currDepth && prevLength == currLength { + return prevMarshal(enc, va, mo) + } + err = errUnsupportedMutation + } if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalJSONTo") // unlike unmarshal, always wrapped } @@ -233,9 +309,9 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { return newUnmarshalErrorAfter(dec, t, errNonStringValue) } s := jsonwire.UnquoteMayCopy(val, flags.IsVerbatim()) - unmarshaler := va.Addr().Interface().(encoding.TextUnmarshaler) + unmarshaler, _ := reflect.TypeAssert[encoding.TextUnmarshaler](va.Addr()) if err := unmarshaler.UnmarshalText(s); err != nil { - err = wrapSkipFunc(err, "unmarshal method") + err = wrapErrUnsupported(err, "UnmarshalText method") if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return err // unlike marshal, never wrapped } @@ -260,9 +336,9 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { if err != nil { return err // must be a syntactic or I/O error } - unmarshaler := va.Addr().Interface().(Unmarshaler) + unmarshaler, _ := reflect.TypeAssert[Unmarshaler](va.Addr()) if err := unmarshaler.UnmarshalJSON(val); err != nil { - err = wrapSkipFunc(err, "unmarshal method") + err = wrapErrUnsupported(err, "UnmarshalJSON method") if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return err // unlike marshal, never wrapped } @@ -283,15 +359,24 @@ func makeMethodArshaler(fncs *arshaler, t reflect.Type) *arshaler { } xd := export.Decoder(dec) prevDepth, prevLength := xd.Tokens.DepthLength() + if prevDepth == 1 && xd.AtEOF() { + return io.EOF // check EOF early to avoid fn reporting an EOF + } xd.Flags.Set(jsonflags.WithinArshalCall | 1) - err := va.Addr().Interface().(UnmarshalerFrom).UnmarshalJSONFrom(dec) + unmarshaler, _ := reflect.TypeAssert[UnmarshalerFrom](va.Addr()) + err := unmarshaler.UnmarshalJSONFrom(dec) xd.Flags.Set(jsonflags.WithinArshalCall | 0) currDepth, currLength := xd.Tokens.DepthLength() if (prevDepth != currDepth || prevLength+1 != currLength) && err == nil { err = errNonSingularValue } if err != nil { - err = wrapSkipFunc(err, "unmarshal method") + if errors.Is(err, errors.ErrUnsupported) { + if prevDepth == currDepth && prevLength == currLength { + return prevUnmarshal(dec, va, uo) + } + err = errUnsupportedMutation + } if uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { if err2 := xd.SkipUntil(prevDepth, prevLength+1); err2 != nil { return err2 diff --git a/vendor/github.com/go-json-experiment/json/arshal_time.go b/vendor/github.com/go-json-experiment/json/arshal_time.go index b8a611e..2d88d04 100644 --- a/vendor/github.com/go-json-experiment/json/arshal_time.go +++ b/vendor/github.com/go-json-experiment/json/arshal_time.go @@ -46,20 +46,26 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) error { xe := export.Encoder(enc) var m durationArshaler - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + if mo.Flags.Has(jsonflags.FormatTag) { if !m.initFormat(mo.Format) { - return newInvalidFormatError(enc, t, mo) + return newInvalidFormatError(enc, t) } } else if mo.Flags.Get(jsonflags.FormatDurationAsNano) { return marshalNano(enc, va, mo) } else { // TODO(https://go.dev/issue/71631): Decide on default duration representation. - return newMarshalErrorBefore(enc, t, errors.New("no default representation (see https://go.dev/issue/71631); specify an explicit format")) + var workaround string + if mo.Flags.Get(jsonflags.FormatTagSupported) { + workaround = "; specify an explicit format" + } + return newMarshalErrorBefore(enc, t, errors.New("no default representation"+workaround)) + } + if mo.Flags.Get(jsonflags.StringTag) && !m.isNumeric() && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) } - // TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo. - m.td = *va.Addr().Interface().(*time.Duration) - k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + m.td, _ = reflect.TypeAssert[time.Duration](va.Value) + k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)) if err := xe.AppendRaw(k, true, m.appendMarshal); err != nil { if !isSyntacticError(err) && !export.IsIOError(err) { err = newMarshalErrorBefore(enc, t, err) @@ -72,20 +78,27 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) error { xd := export.Decoder(dec) var u durationArshaler - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + if uo.Flags.Has(jsonflags.FormatTag) { if !u.initFormat(uo.Format) { - return newInvalidFormatError(dec, t, uo) + return newInvalidFormatError(dec, t) } } else if uo.Flags.Get(jsonflags.FormatDurationAsNano) { return unmarshalNano(dec, va, uo) } else { // TODO(https://go.dev/issue/71631): Decide on default duration representation. - return newUnmarshalErrorBeforeWithSkipping(dec, uo, t, errors.New("no default representation (see https://go.dev/issue/71631); specify an explicit format")) + var workaround string + if uo.Flags.Get(jsonflags.FormatTagSupported) { + workaround = "; specify an explicit format" + } + return newUnmarshalErrorBeforeWithSkipping(dec, t, errors.New("no default representation"+workaround)) + } + if uo.Flags.Get(jsonflags.StringTag) && !u.isNumeric() && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) } - stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) + stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag) var flags jsonwire.ValueFlags - td := va.Addr().Interface().(*time.Duration) + td, _ := reflect.TypeAssert[*time.Duration](va.Addr()) val, err := xd.ReadValue(&flags) if err != nil { return err @@ -123,15 +136,17 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { fncs.marshal = func(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct) (err error) { xe := export.Encoder(enc) var m timeArshaler - if mo.Format != "" && mo.FormatDepth == xe.Tokens.Depth() { + if mo.Flags.Has(jsonflags.FormatTag) { if !m.initFormat(mo.Format) { - return newInvalidFormatError(enc, t, mo) + return newInvalidFormatError(enc, t) } } + if mo.Flags.Get(jsonflags.StringTag) && !m.isNumeric() && !mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newMarshalErrorBefore(enc, t, errInvalidStringTag) + } - // TODO(https://go.dev/issue/62121): Use reflect.Value.AssertTo. - m.tt = *va.Addr().Interface().(*time.Time) - k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers)) + m.tt, _ = reflect.TypeAssert[time.Time](va.Value) + k := stringOrNumberKind(!m.isNumeric() || xe.Tokens.Last.NeedObjectName() || mo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag)) if err := xe.AppendRaw(k, !m.hasCustomFormat(), m.appendMarshal); err != nil { if mo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { return internal.NewMarshalerError(va.Addr().Interface(), err, "MarshalJSON") // unlike unmarshal, always wrapped @@ -146,17 +161,20 @@ func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler { fncs.unmarshal = func(dec *jsontext.Decoder, va addressableValue, uo *jsonopts.Struct) (err error) { xd := export.Decoder(dec) var u timeArshaler - if uo.Format != "" && uo.FormatDepth == xd.Tokens.Depth() { + if uo.Flags.Has(jsonflags.FormatTag) { if !u.initFormat(uo.Format) { - return newInvalidFormatError(dec, t, uo) + return newInvalidFormatError(dec, t) } } else if uo.Flags.Get(jsonflags.ParseTimeWithLooseRFC3339) { u.looseRFC3339 = true } + if uo.Flags.Get(jsonflags.StringTag) && !u.isNumeric() && !uo.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + return newUnmarshalErrorBeforeWithSkipping(dec, t, errInvalidStringTag) + } - stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers) + stringify := !u.isNumeric() || xd.Tokens.Last.NeedObjectName() || uo.Flags.Get(jsonflags.StringifyNumbers|jsonflags.StringTag) var flags jsonwire.ValueFlags - tt := va.Addr().Interface().(*time.Time) + tt, _ := reflect.TypeAssert[*time.Time](va.Addr()) val, err := xd.ReadValue(&flags) if err != nil { return err @@ -467,7 +485,7 @@ func appendDurationISO8601(b []byte, d time.Duration) []byte { } // daysPerYear is the exact average number of days in a year according to -// the Gregorian calender, which has an extra day each year that is +// the Gregorian calendar, which has an extra day each year that is // a multiple of 4, unless it is evenly divisible by 100 but not by 400. // This does not take into account leap seconds, which are not deterministic. const daysPerYear = 365.2425 @@ -496,7 +514,7 @@ var errInaccurateDateUnits = errors.New("inaccurate year, month, week, or day un // between the integer part and fraction part of a number, // as specified in ISO 8601-1:2019, section 3.2.6. // While ISO 8601 recommends comma as the default separator, -// most formatters uses a period. +// most formatters use a period. // // - Leading zeros are ignored. This is not required by ISO 8601, // but also not forbidden by the standard. Many parsers support this. @@ -514,7 +532,7 @@ var errInaccurateDateUnits = errors.New("inaccurate year, month, week, or day un // We follow JavaScript's grammar as JSON itself is derived from JavaScript. // The Temporal.Duration.toJSON method is guaranteed to produce an output // that can be parsed by this function so long as arithmetic in JavaScript -// do not use a largestUnit value higher than "hours" (which is the default). +// does not use a largestUnit value higher than "hours" (which is the default). // Even if it does, this will do a best-effort parsing with inaccurate units, // but report [errInaccurateDateUnits]. func parseDurationISO8601(b []byte) (time.Duration, error) { @@ -541,7 +559,7 @@ func parseDurationISO8601(b []byte) (time.Duration, error) { } // Parse the number. - // A fraction allowed for the accurate units in the last part. + // A fraction is allowed for the accurate units in the last part. whole, frac, ok := cutBytes(number, '.', ',') if ok { sawFrac = true diff --git a/vendor/github.com/go-json-experiment/json/doc.go b/vendor/github.com/go-json-experiment/json/doc.go index a463168..598b50b 100644 --- a/vendor/github.com/go-json-experiment/json/doc.go +++ b/vendor/github.com/go-json-experiment/json/doc.go @@ -9,6 +9,8 @@ // primitive data types such as booleans, strings, and numbers, // in addition to structured data types such as objects and arrays. // +// See the [Working with JSON] tutorial for an introduction to this package. +// // [Marshal] and [Unmarshal] encode and decode Go values // to/from JSON text contained within a []byte. // [MarshalWrite] and [UnmarshalRead] operate on JSON text @@ -53,7 +55,7 @@ // if [RejectUnknownMembers] is specified. // // The representation of each struct field can be customized in the -// "json" struct field tag, where the tag is a comma separated list of options. +// "json" struct field tag, where the tag is a comma-separated list of options. // As a special case, if the entire tag is `json:"-"`, // then the field is ignored with regard to its JSON representation. // Some options also have equivalent behavior controlled by a caller-specified [Options]. @@ -61,11 +63,7 @@ // // The first option is the JSON object name override for the Go struct field. // If the name is not specified, then the Go struct field name -// is used as the JSON object name. JSON names containing commas or quotes, -// or names identical to "" or "-", can be specified using -// a single-quoted string literal, where the syntax is identical to -// the Go grammar for a double-quoted string literal, -// but instead uses single quotes as the delimiters. +// is used as the JSON object name. // By default, unmarshaling uses case-sensitive matching to identify // the Go struct field associated with a JSON object name. // @@ -82,60 +80,49 @@ // encoded as a JSON null, empty string, empty object, or empty array. // This option has no effect when unmarshaling. // -// - string: The "string" option specifies that [StringifyNumbers] -// be set when marshaling or unmarshaling a struct field value. -// This causes numeric types to be encoded as a JSON number -// within a JSON string, and to be decoded from a JSON string -// containing the JSON number without any surrounding whitespace. -// This extra level of encoding is often necessary since -// many JSON parsers cannot precisely represent 64-bit integers. +// - string: The "string" option specifies that [StringifyNumbers] be set +// when marshaling or unmarshaling a struct field value. +// This causes types that would normally be encoded as a JSON number +// to instead be encoded as a JSON number quoted within a JSON string, +// and to be decoded from a JSON string containing the JSON number +// without any surrounding whitespace. +// The "string" option only applies to the top-level of the Go struct field +// value. It is an error to apply this option to any type that does not +// encode as a JSON number. +// Note that composite types such as arrays, slices, structs, and maps do +// not encode as a JSON number, so applying this option will cause an error +// rather than affecting JSON numbers within such types. +// This extra level of encoding is often necessary since many JSON parsers +// cannot precisely represent 64-bit integers. // // - case: When unmarshaling, the "case" option specifies how // JSON object names are matched with the JSON name for Go struct fields. // The option is a key-value pair specified as "case:value" where // the value must either be 'ignore' or 'strict'. -// The 'ignore' value specifies that matching is case-insensitive -// where dashes and underscores are also ignored. If multiple fields match, -// the first declared field in breadth-first order takes precedence. +// The 'ignore' value specifies that matching is case-insensitive, +// and also ignores dashes and underscores. If multiple fields match, +// then the field with an exact name match is selected, otherwise an error +// is reported because the choice of field to unmarshal into is ambiguous. // The 'strict' value specifies that matching is case-sensitive. // This takes precedence over the [MatchCaseInsensitiveNames] option. // -// - inline: The "inline" option specifies that +// - embed: The "embed" option specifies that // the JSON representable content of this field type is to be promoted -// as if they were specified in the parent struct. +// as if it were specified in the parent struct. // It is the JSON equivalent of Go struct embedding. -// A Go embedded field is implicitly inlined unless an explicit JSON name -// is specified. The inlined field must be a Go struct +// A Go embedded field is implicitly JSON embedded unless +// an explicit JSON name is specified. The embedded field must be a Go struct // (that does not implement any JSON methods), [jsontext.Value], // map[~string]T, or an unnamed pointer to such types. When marshaling, -// inlined fields from a pointer type are omitted if it is nil. -// Inlined fields of type [jsontext.Value] and map[~string]T are called -// “inlined fallbacks” as they can represent all possible +// embedded fields from a pointer type are omitted if it is nil. +// Embedded fields of type [jsontext.Value] and map[~string]T are called +// “embedded fallbacks” as they can represent all possible // JSON object members not directly handled by the parent struct. -// Only one inlined fallback field may be specified in a struct, +// Only one embedded fallback field may be specified in a struct, // while many non-fallback fields may be specified. This option // must not be specified with any other option (including the JSON name). // -// - unknown: The "unknown" option is a specialized variant -// of the inlined fallback to indicate that this Go struct field -// contains any number of unknown JSON object members. The field type must -// be a [jsontext.Value], map[~string]T, or an unnamed pointer to such types. -// If [DiscardUnknownMembers] is specified when marshaling, -// the contents of this field are ignored. -// If [RejectUnknownMembers] is specified when unmarshaling, -// any unknown object members are rejected regardless of whether -// an inlined fallback with the "unknown" option exists. This option -// must not be specified with any other option (including the JSON name). -// -// - format: The "format" option specifies a format flag -// used to specialize the formatting of the field value. -// The option is a key-value pair specified as "format:value" where -// the value must be either a literal consisting of letters and numbers -// (e.g., "format:RFC3339") or a single-quoted string literal -// (e.g., "format:'2006-01-02'"). The interpretation of the format flag -// is determined by the struct field type. -// -// The "omitzero" and "omitempty" options are mostly semantically identical. +// The "omitzero" and "omitempty" options behave similarly. // The former is defined in terms of the Go type system, // while the latter in terms of the JSON type system. // Consequently they behave differently in some circumstances. @@ -144,14 +131,14 @@ // The "omitzero" option is useful for types with a well-defined zero value // (e.g., [net/netip.Addr]) or have an IsZero method (e.g., [time.Time.IsZero]). // -// Every Go struct corresponds to a list of JSON representable fields +// Every Go struct corresponds to a list of JSON-representable fields // which is constructed by performing a breadth-first search over // all struct fields (excluding unexported or ignored fields), -// where the search recursively descends into inlined structs. -// The set of non-inlined fields in a struct must have unique JSON names. +// where the search recursively descends into embedded structs. +// The set of non-embedded fields in a struct must have unique JSON names. // If multiple fields all have the same JSON name, then the one // at shallowest depth takes precedence and the other fields at deeper depths -// are excluded from the list of JSON representable fields. +// are excluded from the list of JSON-representable fields. // If multiple fields at the shallowest depth have the same JSON name, // but exactly one is explicitly tagged with a JSON name, // then that field takes precedence and all others are excluded from the list. @@ -159,7 +146,7 @@ // with embedded struct types. // // Marshaling or unmarshaling a non-empty struct -// without any JSON representable fields results in a [SemanticError]. +// without any JSON-representable fields results in a [SemanticError]. // Unexported fields must not have any `json` tags except for `json:"-"`. // // # Security Considerations @@ -171,8 +158,8 @@ // // [For example, suppose we have two micro-services.] // The first service is responsible for authenticating a JSON request, -// while the second service is responsible for executing the request -// (having assumed that the prior service authenticated the request). +// while the second service is responsible for executing the request, +// assuming that it was authenticated. // If an attacker were able to maliciously craft a JSON request such that // both services believe that the same request is from different users, // it could bypass the authenticator with valid credentials for one user, @@ -254,6 +241,7 @@ // The v2 API generally chooses more secure defaults than v1, // but care should still be taken with large integers or unknown members. // +// [Working with JSON]: https://go.dev/doc/tutorial/json // [For example, suppose we have two micro-services.]: https://www.youtube.com/watch?v=avilmOcHKHE&t=1057s package json diff --git a/vendor/github.com/go-json-experiment/json/errors.go b/vendor/github.com/go-json-experiment/json/errors.go index bc7f0b5..85dc437 100644 --- a/vendor/github.com/go-json-experiment/json/errors.go +++ b/vendor/github.com/go-json-experiment/json/errors.go @@ -10,6 +10,7 @@ import ( "cmp" "errors" "fmt" + "io" "reflect" "strconv" "strings" @@ -28,8 +29,8 @@ import ( // The name of an unknown JSON object member can be extracted as: // // err := ... -// var serr json.SemanticError -// if errors.As(err, &serr) && serr.Err == json.ErrUnknownName { +// serr, ok := errors.AsType[*json.SemanticError](err) +// if ok && serr.Err == json.ErrUnknownName { // ptr := serr.JSONPointer // JSON pointer to unknown name // name := ptr.LastToken() // unknown name itself // ... @@ -38,6 +39,10 @@ import ( // This error is only returned if [RejectUnknownMembers] is true. var ErrUnknownName = errors.New("unknown object member name") +// errAmbiguousName indicates a JSON object member could be unmarshal +// into multiple candidate Go struct fields. +var errAmbiguousName = errors.New("ambiguous object member name") + const errorPrefix = "json: " func isSemanticError(err error) bool { @@ -50,7 +55,7 @@ func isSyntacticError(err error) bool { return ok } -// isFatalError reports whether this error must terminate asharling. +// isFatalError reports whether this error must terminate arshaling. // All errors are considered fatal unless operating under // [jsonflags.ReportErrorsWithLegacySemantics] in which case only // syntactic errors and I/O errors are considered fatal. @@ -60,7 +65,12 @@ func isFatalError(err error, flags jsonflags.Flags) bool { } // SemanticError describes an error determining the meaning -// of JSON data as Go data or vice-versa. +// of JSON data as Go data, or vice versa. +// +// If a [Marshaler], [MarshalerTo], [Unmarshaler], or [UnmarshalerFrom] method +// returns a SemanticError when called by the [json] package, +// then the ByteOffset, JSONPointer, and GoType fields are automatically +// populated by the calling context if they are the zero value. // // The contents of this error as produced by this package may change over time. type SemanticError struct { @@ -69,7 +79,7 @@ type SemanticError struct { action string // either "marshal" or "unmarshal" - // ByteOffset indicates that an error occurred after this byte offset. + // ByteOffset indicates that an error occurred at or after this byte offset. ByteOffset int64 // JSONPointer indicates that an error occurred within this JSON value // as indicated using the JSON Pointer notation (see RFC 6901). @@ -88,22 +98,25 @@ type SemanticError struct { } // coder is implemented by [jsontext.Encoder] or [jsontext.Decoder]. -type coder interface{ StackPointer() jsontext.Pointer } +type coder interface { + StackPointer() jsontext.Pointer + Options() Options +} -// newInvalidFormatError wraps err in a SemanticError because +// newInvalidFormatError constructs a SemanticError because // the current type t cannot handle the provided options format. -// This error must be called before producing or consuming the next value. +// This function must be called before producing or consuming the next value. // // If [jsonflags.ReportErrorsWithLegacySemantics] is specified, // then this automatically skips the next value when unmarshaling // to ensure that the value is fully consumed. -func newInvalidFormatError(c coder, t reflect.Type, o *jsonopts.Struct) error { - err := fmt.Errorf("invalid format flag %q", o.Format) +func newInvalidFormatError(c coder, t reflect.Type) error { + err := fmt.Errorf("invalid format flag %q", c.Options().(*jsonopts.Struct).Format) switch c := c.(type) { case *jsontext.Encoder: err = newMarshalErrorBefore(c, t, err) case *jsontext.Decoder: - err = newUnmarshalErrorBeforeWithSkipping(c, o, t, err) + err = newUnmarshalErrorBeforeWithSkipping(c, t, err) } return err } @@ -111,7 +124,7 @@ func newInvalidFormatError(c coder, t reflect.Type, o *jsonopts.Struct) error { // newMarshalErrorBefore wraps err in a SemanticError assuming that e // is positioned right before the next token or value, which causes an error. func newMarshalErrorBefore(e *jsontext.Encoder, t reflect.Type, err error) error { - return &SemanticError{action: "marshal", GoType: t, Err: err, + return &SemanticError{action: "marshal", GoType: t, Err: toUnexpectedEOF(err), ByteOffset: e.OutputOffset() + int64(export.Encoder(e).CountNextDelimWhitespace()), JSONPointer: jsontext.Pointer(export.Encoder(e).AppendStackPointer(nil, +1))} } @@ -127,7 +140,7 @@ func newUnmarshalErrorBefore(d *jsontext.Decoder, t reflect.Type, err error) err if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { k = d.PeekKind() } - return &SemanticError{action: "unmarshal", GoType: t, Err: err, + return &SemanticError{action: "unmarshal", GoType: t, Err: toUnexpectedEOF(err), ByteOffset: d.InputOffset() + int64(export.Decoder(d).CountNextDelimWhitespace()), JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, +1)), JSONKind: k} @@ -136,9 +149,9 @@ func newUnmarshalErrorBefore(d *jsontext.Decoder, t reflect.Type, err error) err // newUnmarshalErrorBeforeWithSkipping is like [newUnmarshalErrorBefore], // but automatically skips the next value if // [jsonflags.ReportErrorsWithLegacySemantics] is specified. -func newUnmarshalErrorBeforeWithSkipping(d *jsontext.Decoder, o *jsonopts.Struct, t reflect.Type, err error) error { +func newUnmarshalErrorBeforeWithSkipping(d *jsontext.Decoder, t reflect.Type, err error) error { err = newUnmarshalErrorBefore(d, t, err) - if o.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { if err2 := export.Decoder(d).SkipValue(); err2 != nil { return err2 } @@ -150,13 +163,22 @@ func newUnmarshalErrorBeforeWithSkipping(d *jsontext.Decoder, o *jsonopts.Struct // is positioned right after the previous token or value, which caused an error. func newUnmarshalErrorAfter(d *jsontext.Decoder, t reflect.Type, err error) error { tokOrVal := export.Decoder(d).PreviousTokenOrValue() - return &SemanticError{action: "unmarshal", GoType: t, Err: err, - ByteOffset: d.InputOffset() - int64(len(tokOrVal)), + byteOffset := d.InputOffset() - int64(len(tokOrVal)) + if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + // NOTE: In v1, the offset pointed to the end of the bad token or value. + if k := jsontext.Value(tokOrVal).Kind(); k == '[' || k == '{' { + byteOffset++ // add just the '[' or '{' + } else { + byteOffset += int64(len(tokOrVal)) + } + } + return &SemanticError{action: "unmarshal", GoType: t, Err: toUnexpectedEOF(err), + ByteOffset: byteOffset, JSONPointer: jsontext.Pointer(export.Decoder(d).AppendStackPointer(nil, -1)), JSONKind: jsontext.Value(tokOrVal).Kind()} } -// newUnmarshalErrorAfter wraps err in a SemanticError assuming that d +// newUnmarshalErrorAfterWithValue wraps err in a SemanticError assuming that d // is positioned right after the previous token or value, which caused an error. // It also stores a copy of the last JSON value if it is a string or number. func newUnmarshalErrorAfterWithValue(d *jsontext.Decoder, t reflect.Type, err error) error { @@ -170,9 +192,9 @@ func newUnmarshalErrorAfterWithValue(d *jsontext.Decoder, t reflect.Type, err er // newUnmarshalErrorAfterWithSkipping is like [newUnmarshalErrorAfter], // but automatically skips the remainder of the current value if // [jsonflags.ReportErrorsWithLegacySemantics] is specified. -func newUnmarshalErrorAfterWithSkipping(d *jsontext.Decoder, o *jsonopts.Struct, t reflect.Type, err error) error { +func newUnmarshalErrorAfterWithSkipping(d *jsontext.Decoder, t reflect.Type, err error) error { err = newUnmarshalErrorAfter(d, t, err) - if o.Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { + if export.Decoder(d).Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) { if err2 := export.Decoder(d).SkipValueRemainder(); err2 != nil { return err2 } @@ -199,6 +221,7 @@ func newSemanticErrorWithPosition(c coder, t reflect.Type, prevDepth int, prevLe if serr == nil { serr = &SemanticError{Err: err} } + serr.Err = toUnexpectedEOF(serr.Err) var currDepth int var currLength int64 var coderState interface{ AppendStackPointer([]byte, int) []byte } @@ -289,6 +312,13 @@ func collapseSemanticErrors(err error) error { return err } +func wrapErrUnsupported(err error, what string) error { + if errors.Is(err, errors.ErrUnsupported) { + return errors.New(what + " may not return errors.ErrUnsupported") + } + return err +} + // errorModalVerb is a modal verb like "cannot" or "unable to". // // Once per process, Hyrum-proof the error message by deliberately @@ -370,9 +400,9 @@ func (e *SemanticError) Error() string { } // Special handling for unknown names. - if e.Err == ErrUnknownName { + if e.Err == ErrUnknownName || e.Err == errAmbiguousName { sb.WriteString(": ") - sb.WriteString(ErrUnknownName.Error()) + sb.WriteString(e.Err.Error()) sb.WriteString(" ") sb.WriteString(strconv.Quote(e.JSONPointer.LastToken())) if parent := e.JSONPointer.Parent(); parent != "" { @@ -425,3 +455,11 @@ func newDuplicateNameError(ptr jsontext.Pointer, quotedName []byte, offset int64 Err: jsontext.ErrDuplicateName, } } + +// toUnexpectedEOF converts [io.EOF] to [io.ErrUnexpectedEOF]. +func toUnexpectedEOF(err error) error { + if err == io.EOF { + return io.ErrUnexpectedEOF + } + return err +} diff --git a/vendor/github.com/go-json-experiment/json/fields.go b/vendor/github.com/go-json-experiment/json/fields.go index a164f00..7aa6592 100644 --- a/vendor/github.com/go-json-experiment/json/fields.go +++ b/vendor/github.com/go-json-experiment/json/fields.go @@ -29,10 +29,12 @@ type isZeroer interface { var isZeroerType = reflect.TypeFor[isZeroer]() type structFields struct { - flattened []structField // listed in depth-first ordering - byActualName map[string]*structField - byFoldedName map[string][]*structField - inlinedFallback *structField + flattened []structField // listed in depth-first ordering + byActualName map[string]*structField + byFoldedName map[string][]*structField + embeddedFallback *structField + + errUnsupportedFormat *SemanticError } // reindex recomputes index to avoid bounds check during runtime. @@ -51,8 +53,8 @@ func (sf *structFields) reindex() { for i := range sf.flattened { reindex(&sf.flattened[i]) } - if sf.inlinedFallback != nil { - reindex(sf.inlinedFallback) + if sf.embeddedFallback != nil { + reindex(sf.embeddedFallback) } } @@ -80,25 +82,25 @@ func makeStructFields(root reflect.Type) (fs structFields, serr *SemanticError) return cmp.Or(serr, &SemanticError{GoType: t, Err: fmt.Errorf(f, a...)}) } - // Setup a queue for a breath-first search. + // Setup a queue for a breadth-first search. var queueIndex int type queueEntry struct { typ reflect.Type index []int - visitChildren bool // whether to recursively visit inlined field in this struct + visitChildren bool // whether to recursively visit embedded field in this struct } queue := []queueEntry{{root, nil, true}} seen := map[reflect.Type]bool{root: true} // Perform a breadth-first search over all reachable fields. // This ensures that len(f.index) will be monotonically increasing. - var allFields, inlinedFallbacks []structField + var allFields, embeddedFallbacks []structField for queueIndex < len(queue) { qe := queue[queueIndex] queueIndex++ t := qe.typ - inlinedFallbackIndex := -1 // index of last inlined fallback field in current struct + embeddedFallbackIndex := -1 // index of last embedded fallback field in current struct namesIndex := make(map[string]int) // index of each field with a given JSON object name in current struct var hasAnyJSONTag bool // whether any Go struct field has a `json` tag var hasAnyJSONField bool // whether any JSON serializable fields exist in current struct @@ -126,80 +128,73 @@ func makeStructFields(root reflect.Type) (fs structFields, serr *SemanticError) if indirectType(f.typ).Kind() != reflect.Struct { serr = orErrorf(serr, t, "embedded Go struct field %s of non-struct type must be explicitly given a JSON name", sf.Name) } else { - f.inline = true // implied by use of Go embedding without an explicit name + f.embed = true // implied by use of Go embedding without an explicit name } } - if f.inline || f.unknown { - // Handle an inlined field that serializes to/from + + var handleEmbed, handleField func() + handleEmbed = func() { + // Handle an embedded field that serializes to/from // zero or more JSON object members. - switch f.fieldOptions { - case fieldOptions{name: f.name, quotedName: f.quotedName, inline: true}: - case fieldOptions{name: f.name, quotedName: f.quotedName, unknown: true}: - case fieldOptions{name: f.name, quotedName: f.quotedName, inline: true, unknown: true}: - serr = orErrorf(serr, t, "Go struct field %s cannot have both `inline` and `unknown` specified", sf.Name) - f.inline = false // let `unknown` take precedence - default: - serr = orErrorf(serr, t, "Go struct field %s cannot have any options other than `inline` or `unknown` specified", sf.Name) + if f.fieldOptions != (fieldOptions{name: f.name, quotedName: f.quotedName, embed: true}) { + serr = orErrorf(serr, t, "Go struct field %s cannot have any options other than `embed` specified", sf.Name) if f.hasName { - continue // invalid inlined field; treat as ignored - } - f.fieldOptions = fieldOptions{name: f.name, quotedName: f.quotedName, inline: f.inline, unknown: f.unknown} - if f.inline && f.unknown { - f.inline = false // let `unknown` take precedence + handleField() + return // invalid embedded field; treat as regular field } + f.fieldOptions = fieldOptions{name: f.name, quotedName: f.quotedName, embed: f.embed} } // Reject any types with custom serialization otherwise - // it becomes impossible to know what sub-fields to inline. + // it becomes impossible to know what sub-fields to embed. tf := indirectType(f.typ) if implementsAny(tf, allMethodTypes...) && tf != jsontextValueType { - serr = orErrorf(serr, t, "inlined Go struct field %s of type %s must not implement marshal or unmarshal methods", sf.Name, tf) + serr = orErrorf(serr, t, "embedded Go struct field %s of type %s must not implement marshal or unmarshal methods", sf.Name, tf) } - // Handle an inlined field that serializes to/from + // Handle an embedded field that serializes to/from // a finite number of JSON object members backed by a Go struct. if tf.Kind() == reflect.Struct { - if f.unknown { - serr = orErrorf(serr, t, "inlined Go struct field %s of type %s with `unknown` tag must be a Go map of string key or a jsontext.Value", sf.Name, tf) - continue // invalid inlined field; treat as ignored - } if qe.visitChildren { queue = append(queue, queueEntry{tf, f.index, !seen[tf]}) } seen[tf] = true - continue + return } else if !sf.IsExported() { - serr = orErrorf(serr, t, "inlined Go struct field %s is not exported", sf.Name) - continue // invalid inlined field; treat as ignored + serr = orErrorf(serr, t, "embedded Go struct field %s is not exported", sf.Name) + return // invalid embedded field; treat as ignored } - // Handle an inlined field that serializes to/from any number of + // Handle an embedded field that serializes to/from any number of // JSON object members back by a Go map or jsontext.Value. switch { case tf == jsontextValueType: - f.fncs = nil // specially handled in arshal_inlined.go + f.fncs = nil // specially handled in arshal_embedded.go case tf.Kind() == reflect.Map && tf.Key().Kind() == reflect.String: if implementsAny(tf.Key(), allMethodTypes...) { - serr = orErrorf(serr, t, "inlined map field %s of type %s must have a string key that does not implement marshal or unmarshal methods", sf.Name, tf) - continue // invalid inlined field; treat as ignored + serr = orErrorf(serr, t, "embedded map field %s of type %s must have a string key that does not implement marshal or unmarshal methods", sf.Name, tf) + handleField() + return // invalid embedded field; treat as regular field } f.fncs = lookupArshaler(tf.Elem()) default: - serr = orErrorf(serr, t, "inlined Go struct field %s of type %s must be a Go struct, Go map of string key, or jsontext.Value", sf.Name, tf) - continue // invalid inlined field; treat as ignored + serr = orErrorf(serr, t, "embedded Go struct field %s of type %s must be a Go struct, Go map of string key, or jsontext.Value", sf.Name, tf) + handleField() + return // invalid embedded field; treat as regular field } - // Reject multiple inlined fallback fields within the same struct. - if inlinedFallbackIndex >= 0 { - serr = orErrorf(serr, t, "inlined Go struct fields %s and %s cannot both be a Go map or jsontext.Value", t.Field(inlinedFallbackIndex).Name, sf.Name) - // Still append f to inlinedFallbacks as there is still a - // check for a dominant inlined fallback before returning. + // Reject multiple embedded fallback fields within the same struct. + if embeddedFallbackIndex >= 0 { + serr = orErrorf(serr, t, "embedded Go struct fields %s and %s cannot both be a Go map or jsontext.Value", t.Field(embeddedFallbackIndex).Name, sf.Name) + // Still append f to embeddedFallbacks as there is still a + // check for a dominant embedded fallback before returning. } - inlinedFallbackIndex = i + embeddedFallbackIndex = i - inlinedFallbacks = append(inlinedFallbacks, f) - } else { + embeddedFallbacks = append(embeddedFallbacks, f) + } + handleField = func() { // Handle normal Go struct field that serializes to/from // a single JSON object member. @@ -210,14 +205,14 @@ func makeStructFields(root reflect.Type) (fs structFields, serr *SemanticError) tf := indirectType(f.typ) if !(sf.Anonymous && tf.Kind() == reflect.Struct) { serr = orErrorf(serr, t, "Go struct field %s is not exported", sf.Name) - continue + return } // Unfortunately, methods on the unexported field // still cannot be called. if implementsAny(tf, allMethodTypes...) || (f.omitzero && implementsAny(tf, isZeroerType)) { serr = orErrorf(serr, t, "Go struct field %s is not exported for method calls", sf.Name) - continue + return } } @@ -260,6 +255,15 @@ func makeStructFields(root reflect.Type) (fs structFields, serr *SemanticError) f.id = len(allFields) f.fncs = lookupArshaler(sf.Type) allFields = append(allFields, f) + if f.format != "" && fs.errUnsupportedFormat == nil { + fs.errUnsupportedFormat = &SemanticError{GoType: t, Err: fmt.Errorf("Go struct field %s has unsupported `format` tag option", sf.Name)} + } + } + + if f.embed { + handleEmbed() + } else { + handleField() } } @@ -325,6 +329,8 @@ func makeStructFields(root reflect.Type) (fs structFields, serr *SemanticError) flattened: flattened, byActualName: make(map[string]*structField, len(flattened)), byFoldedName: make(map[string][]*structField, len(flattened)), + + errUnsupportedFormat: fs.errUnsupportedFormat, } for i, f := range fs.flattened { foldedName := string(foldName([]byte(f.name))) @@ -333,7 +339,7 @@ func makeStructFields(root reflect.Type) (fs structFields, serr *SemanticError) } for foldedName, fields := range fs.byFoldedName { if len(fields) > 1 { - // The precedence order for conflicting ignoreCase names + // The precedence order for conflicting case-insensitive names // is by breadth-first order, rather than depth-first order. slices.SortFunc(fields, func(x, y *structField) int { return cmp.Compare(x.id, y.id) @@ -341,8 +347,8 @@ func makeStructFields(root reflect.Type) (fs structFields, serr *SemanticError) fs.byFoldedName[foldedName] = fields } } - if n := len(inlinedFallbacks); n == 1 || (n > 1 && len(inlinedFallbacks[0].index) != len(inlinedFallbacks[1].index)) { - fs.inlinedFallback = &inlinedFallbacks[0] // dominant inlined fallback field + if n := len(embeddedFallbacks); n == 1 || (n > 1 && len(embeddedFallbacks[0].index) != len(embeddedFallbacks[1].index)) { + fs.embeddedFallback = &embeddedFallbacks[0] // dominant embedded fallback field } fs.reindex() return fs, serr @@ -391,8 +397,7 @@ type fieldOptions struct { hasName bool nameNeedEscape bool casing int8 // either 0, caseIgnore, or caseStrict - inline bool - unknown bool + embed bool omitzero bool omitempty bool string bool @@ -404,7 +409,6 @@ type fieldOptions struct { // the JSON member name and other features. func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, err error) { tag, hasTag := sf.Tag.Lookup("json") - tagOrig := tag // Check whether this field is explicitly ignored. if tag == "-" { @@ -428,10 +432,7 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, return fieldOptions{}, true, err } - // Determine the JSON member name for this Go field. A user-specified name - // may be provided as either an identifier or a single-quoted string. - // The single-quoted string allows arbitrary characters in the name. - // See https://go.dev/issue/2718 and https://go.dev/issue/3546. + // Determine the JSON member name for this Go field. out.name = sf.Name // always starts with an uppercase character if len(tag) > 0 && !strings.HasPrefix(tag, ",") { // For better compatibility with v1, accept almost any unescaped name. @@ -445,7 +446,7 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, // In either case, call consumeTagOption to handle it further. var err2 error if !strings.HasPrefix(tag[n:], ",") && len(name) != len(tag) { - name, n, err2 = consumeTagOption(tag) + name, n, err2 = consumeTagOption(tag, false) if err2 != nil { err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed `json` tag: %v", sf.Name, err2)) } @@ -454,22 +455,15 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, err = cmp.Or(err, fmt.Errorf("Go struct field %s has JSON object name %q with invalid UTF-8", sf.Name, name)) name = string([]rune(name)) // replace invalid UTF-8 with utf8.RuneError } - if name == "-" && tag[0] == '-' { - defer func() { // defer to let other errors take precedence - err = cmp.Or(err, fmt.Errorf("Go struct field %s has JSON object name %q; either "+ - "use `json:\"-\"` to ignore the field or "+ - "use `json:\"'-'%s` to specify %q as the name", sf.Name, out.name, strings.TrimPrefix(strconv.Quote(tagOrig), `"-`), name)) - }() - } if err2 == nil { out.hasName = true out.name = name } tag = tag[n:] } - b, _ := jsonwire.AppendQuote(nil, out.name, &jsonflags.Flags{}) + b, _ := jsonwire.AppendQuote(nil, []byte(out.name), &jsonflags.Flags{}) out.quotedName = string(b) - out.nameNeedEscape = jsonwire.NeedEscape(out.name) + out.nameNeedEscape = jsonwire.NeedEscape([]byte(out.name)) // Handle any additional tag options (if any). var wasFormat bool @@ -487,7 +481,7 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, } // Consume and process the tag option. - opt, n, err2 := consumeTagOption(tag) + opt, n, err2 := consumeTagOption(tag, false) if err2 != nil { err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed `json` tag: %v", sf.Name, err2)) } @@ -506,7 +500,7 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, break } tag = tag[len(":"):] - opt, n, err2 := consumeTagOption(tag) + opt, n, err2 := consumeTagOption(tag, false) if err2 != nil { err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed value for `case` tag option: %v", sf.Name, err2)) break @@ -524,10 +518,8 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, default: err = cmp.Or(err, fmt.Errorf("Go struct field %s has unknown `case:%s` tag value", sf.Name, rawOpt)) } - case "inline": - out.inline = true - case "unknown": - out.unknown = true + case "embed": + out.embed = true case "omitzero": out.omitzero = true case "omitempty": @@ -540,10 +532,13 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, break } tag = tag[len(":"):] - opt, n, err2 := consumeTagOption(tag) + opt, n, err2 := consumeTagOption(tag, true) if err2 != nil { err = cmp.Or(err, fmt.Errorf("Go struct field %s has malformed value for `format` tag option: %v", sf.Name, err2)) break + } else if opt == "" { + err = cmp.Or(err, fmt.Errorf("Go struct field %s cannot have empty value for `format` tag option", sf.Name)) + break } tag = tag[n:] out.format = opt @@ -553,7 +548,7 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, // This catches invalid mutants such as "omitEmpty" or "omit_empty". normOpt := strings.ReplaceAll(strings.ToLower(opt), "_", "") switch normOpt { - case "case", "inline", "unknown", "omitzero", "omitempty", "string", "format": + case "case", "embed", "omitzero", "omitempty", "string", "format": err = cmp.Or(err, fmt.Errorf("Go struct field %s has invalid appearance of `%s` tag option; specify `%s` instead", sf.Name, opt, normOpt)) } @@ -578,7 +573,7 @@ func parseFieldOptions(sf reflect.StructField) (out fieldOptions, ignored bool, // which is either a Go identifier or a single-quoted string. // If the next option is invalid, it returns all of in until the next comma, // and reports an error. -func consumeTagOption(in string) (string, int, error) { +func consumeTagOption(in string, allowQuoted bool) (string, int, error) { // For legacy compatibility with v1, assume options are comma-separated. i := strings.IndexByte(in, ',') if i < 0 { @@ -592,6 +587,10 @@ func consumeTagOption(in string) (string, int, error) { return in[:n], n, nil // Option as a single-quoted string. case r == '\'': + if !allowQuoted { + return in[:i], i, fmt.Errorf("invalid character %q at start of option (expecting Unicode letter)", r) + } + // The grammar is nearly identical to a double-quoted Go string literal, // but uses single quotes as the terminators. The reason for a custom // grammar is because both backtick and double quotes cannot be used @@ -633,6 +632,9 @@ func consumeTagOption(in string) (string, int, error) { case len(in) == 0: return in[:i], i, io.ErrUnexpectedEOF default: + if !allowQuoted { + return in[:i], i, fmt.Errorf("invalid character %q at start of option (expecting Unicode letter)", r) + } return in[:i], i, fmt.Errorf("invalid character %q at start of option (expecting Unicode letter or single quote)", r) } } diff --git a/vendor/github.com/go-json-experiment/json/intern.go b/vendor/github.com/go-json-experiment/json/intern.go index 1bfb8ca..a9774db 100644 --- a/vendor/github.com/go-json-experiment/json/intern.go +++ b/vendor/github.com/go-json-experiment/json/intern.go @@ -56,7 +56,7 @@ func makeString(c *stringCache, b []byte) string { // hash64 returns the hash of two uint32s as a single uint32. func hash64(lo, hi uint32) uint32 { - // If avalanche=true, this is identical to XXH32 hash on a 8B string: + // If avalanche=true, this is identical to XXH32 hash on an 8B string: // var b [8]byte // binary.LittleEndian.PutUint32(b[:4], lo) // binary.LittleEndian.PutUint32(b[4:], hi) @@ -75,7 +75,7 @@ func hash64(lo, hi uint32) uint32 { h = bits.RotateLeft32(h, 17) * prime4 // Skip final mix (avalanche) step of XXH32 for performance reasons. // Empirical testing shows that the improvements in unbiased distribution - // does not outweigh the extra cost in computational complexity. + // do not outweigh the extra cost in computational complexity. const avalanche = false if avalanche { h ^= h >> 15 diff --git a/vendor/github.com/go-json-experiment/json/internal/internal.go b/vendor/github.com/go-json-experiment/json/internal/internal.go index 00b43fa..c8591c1 100644 --- a/vendor/github.com/go-json-experiment/json/internal/internal.go +++ b/vendor/github.com/go-json-experiment/json/internal/internal.go @@ -32,7 +32,7 @@ var ( // It is called after a user-defined Marshal method/function fails. NewMarshalerError func(any, error, string) error // TransformUnmarshalError converts a v2 error into a v1 error. - // It is called only at the top-level of a Unmarshal function. + // It is called only at the top-level of an Unmarshal function. TransformUnmarshalError func(any, error) error // NewRawNumber returns new(jsonv1.Number). diff --git a/vendor/github.com/go-json-experiment/json/internal/jsonflags/flags.go b/vendor/github.com/go-json-experiment/json/internal/jsonflags/flags.go index 3708344..20a36fb 100644 --- a/vendor/github.com/go-json-experiment/json/internal/jsonflags/flags.go +++ b/vendor/github.com/go-json-experiment/json/internal/jsonflags/flags.go @@ -43,9 +43,10 @@ const ( ByteLimit | DepthLimit | Marshalers | - Unmarshalers + Unmarshalers | + FormatTag - // DefaultV1Flags is the set of booleans flags that default to true under + // DefaultV1Flags is the set of boolean flags that default to true under // v1 semantics. None of the non-boolean flags differ between v1 and v2. DefaultV1Flags = 0 | AllowDuplicateNames | @@ -83,6 +84,12 @@ const ( // CanonicalizeNumbers is the set of flags related to raw number canonicalization. CanonicalizeNumbers = CanonicalizeRawInts | CanonicalizeRawFloats + + // TagFlags is the set of flags related to the presence of struct field tags. + // Tags have non-recursive effects, where the tag only applies to + // the top-level of the field value itself. + // Whenever descending into a JSON object or array, these flags are cleared. + TagFlags = StringTag | FormatTag ) // Encoder and decoder flags. @@ -120,10 +127,12 @@ const ( FormatNilSliceAsNull // marshal only OmitZeroStructFields // marshal only MatchCaseInsensitiveNames // marshal or unmarshal - DiscardUnknownMembers // marshal only RejectUnknownMembers // unmarshal only Marshalers // marshal only; non-boolean flag Unmarshalers // unmarshal only; non-boolean flag + StringTag // marshal or unmarshal + FormatTag // marshal or unmarshal; non-boolean flag + FormatTagSupported // marshal or unmarshal maxArshalV2Flag ) @@ -143,7 +152,6 @@ const ( ParseTimeWithLooseRFC3339 // unmarshal ReportErrorsWithLegacySemantics // marshal or unmarshal StringifyWithLegacySemantics // marshal or unmarshal - StringifyBoolsAndStrings // marshal or unmarshal; for internal use by jsonv2.makeStructArshaler UnmarshalAnyWithRawNumber // unmarshal; for internal use by jsonv1.Decoder.UseNumber UnmarshalArrayFromAnyLength // unmarshal @@ -151,7 +159,7 @@ const ( ) // bitsUsed is the number of bits used in the 64-bit boolean flags -const bitsUsed = 42 +const bitsUsed = 43 // Static compile check that bitsUsed and maxArshalV1Flag are in sync. const _ = uint64((1< 0b_110_11011 - dst.Values &= ^src.Presence // e.g., 0b_1000_0011 & 0b_1010_0101 -> 0b_100_00001 - dst.Values |= src.Values // e.g., 0b_1000_0001 | 0b_1001_0010 -> 0b_100_10011 + // e.g., dst := Flags{Presence: 0b_1100_0011, Values: 0b_1000_0011} + // e.g., src := Flags{Presence: 0b_0101_1010, Values: 0b_1001_0010} + dst.Presence |= src.Presence // e.g., 0b_1100_0011 | 0b_0101_1010 -> 0b_1101_1011 + dst.Values &= ^src.Presence // e.g., 0b_1000_0011 & 0b_1010_0101 -> 0b_1000_0001 + dst.Values |= src.Values // e.g., 0b_1000_0001 | 0b_1001_0010 -> 0b_1001_0011 } // Set sets both the presence and value for the provided bool (or set of bools). @@ -182,10 +190,10 @@ func (fs *Flags) Set(f Bools) { // then set the presence for all the identifier bits (using OR), // then invert the identifier bits to clear out the values (using AND-NOT), // then copy over all the identifier bits to the value if LSB is 1. - // e.g., fs := Flags{Presence: 0b_0101_0010, Value: 0b_0001_0010} + // e.g., fs := Flags{Presence: 0b_0101_0010, Values: 0b_0001_0010} // e.g., f := 0b_1001_0001 id := uint64(f) &^ uint64(1) // e.g., 0b_1001_0001 & 0b_1111_1110 -> 0b_1001_0000 - fs.Presence |= id // e.g., 0b_0101_0010 | 0b_1001_0000 -> 0b_1101_0011 + fs.Presence |= id // e.g., 0b_0101_0010 | 0b_1001_0000 -> 0b_1101_0010 fs.Values &= ^id // e.g., 0b_0001_0010 & 0b_0110_1111 -> 0b_0000_0010 fs.Values |= uint64(f&1) * id // e.g., 0b_0000_0010 | 0b_1001_0000 -> 0b_1001_0010 } @@ -207,7 +215,7 @@ func (fs Flags) Has(f Bools) bool { // The value bit of f (i.e., the LSB) is ignored. func (fs *Flags) Clear(f Bools) { // Invert f to produce a mask to clear all bits in f (using AND). - // e.g., fs := Flags{Presence: 0b_0101_0010, Value: 0b_0001_0010} + // e.g., fs := Flags{Presence: 0b_0101_0010, Values: 0b_0001_0010} // e.g., f := 0b_0001_1000 mask := uint64(^f) // e.g., 0b_0001_1000 -> 0b_1110_0111 fs.Presence &= mask // e.g., 0b_0101_0010 & 0b_1110_0111 -> 0b_0100_0010 diff --git a/vendor/github.com/go-json-experiment/json/internal/jsonopts/options.go b/vendor/github.com/go-json-experiment/json/internal/jsonopts/options.go index f0bd678..d32eb80 100644 --- a/vendor/github.com/go-json-experiment/json/internal/jsonopts/options.go +++ b/vendor/github.com/go-json-experiment/json/internal/jsonopts/options.go @@ -17,6 +17,11 @@ type Options interface { JSONOptions(internal.NotForPublicUse) } +// experimentalFormatTagSupporter is a special option method that allows +// [github.com/go-json-experiment/json.ExperimentalSupportFormatTag] +// to enable experimental `format` tag functionality at runtime. +type experimentalFormatTagSupporter interface{ ExperimentalSupportFormatTag() bool } + // Struct is the combination of all options in struct form. // This is efficient to pass down the call stack and to query. type Struct struct { @@ -41,23 +46,22 @@ type ArshalValues struct { Marshalers any // jsonflags.Marshalers Unmarshalers any // jsonflags.Unmarshalers - Format string - FormatDepth int + Format string // valid if jsonflags.FormatTag is set } // DefaultOptionsV2 is the set of all options that define default v2 behavior. var DefaultOptionsV2 = Struct{ Flags: jsonflags.Flags{ - Presence: uint64(jsonflags.AllFlags & ^jsonflags.WhitespaceFlags), - Values: uint64(0), + Presence: uint64(jsonflags.DefaultV1Flags), + Values: uint64(0), // all flags in DefaultV1Flags are false }, } // DefaultOptionsV1 is the set of all options that define default v1 behavior. var DefaultOptionsV1 = Struct{ Flags: jsonflags.Flags{ - Presence: uint64(jsonflags.AllFlags & ^jsonflags.WhitespaceFlags), - Values: uint64(jsonflags.DefaultV1Flags), + Presence: uint64(jsonflags.DefaultV1Flags), + Values: uint64(jsonflags.DefaultV1Flags), // all flags in DefaultV1Flags are true }, } @@ -82,6 +86,13 @@ func GetOption[T any](opts Options, setter func(T) Options) (T, bool) { case jsonflags.Bools: v := structOpts.Flags.Get(opt) ok := structOpts.Flags.Has(opt) + if !ok && opt == jsonflags.StringifyNumbers && structOpts.Flags.Get(jsonflags.StringTag) { + return any(true).(T), true // check also whether the option is specified via a `string` tag + } + return any(v).(T), ok + case experimentalFormatTagSupporter: + v := structOpts.Flags.Get(jsonflags.FormatTagSupported) + ok := structOpts.Flags.Has(jsonflags.FormatTagSupported) return any(v).(T), ok case Indent: if !structOpts.Flags.Has(jsonflags.Indent) { @@ -114,72 +125,54 @@ func GetOption[T any](opts Options, setter func(T) Options) (T, bool) { var JoinUnknownOption = func(Struct, Options) Struct { panic("unknown option") } func (dst *Struct) Join(srcs ...Options) { - dst.join(false, srcs...) -} - -func (dst *Struct) JoinWithoutCoderOptions(srcs ...Options) { - dst.join(true, srcs...) -} - -func (dst *Struct) join(excludeCoderOptions bool, srcs ...Options) { for _, src := range srcs { switch src := src.(type) { case nil: continue case jsonflags.Bools: - if excludeCoderOptions { - src &= ^jsonflags.AllCoderFlags - } dst.Flags.Set(src) - case Indent: - if excludeCoderOptions { - continue + case experimentalFormatTagSupporter: + if src.ExperimentalSupportFormatTag() { + dst.Flags.Set(jsonflags.FormatTagSupported | 1) + } else { + dst.Flags.Set(jsonflags.FormatTagSupported | 0) } + case Indent: dst.Flags.Set(jsonflags.Multiline | jsonflags.Indent | 1) dst.Indent = string(src) case IndentPrefix: - if excludeCoderOptions { - continue - } dst.Flags.Set(jsonflags.Multiline | jsonflags.IndentPrefix | 1) dst.IndentPrefix = string(src) case ByteLimit: - if excludeCoderOptions { - continue - } dst.Flags.Set(jsonflags.ByteLimit | 1) dst.ByteLimit = int64(src) case DepthLimit: - if excludeCoderOptions { - continue - } dst.Flags.Set(jsonflags.DepthLimit | 1) dst.DepthLimit = int(src) case *Struct: - srcFlags := src.Flags // shallow copy the flags - if excludeCoderOptions { - srcFlags.Clear(jsonflags.AllCoderFlags) - } - dst.Flags.Join(srcFlags) - if srcFlags.Has(jsonflags.NonBooleanFlags) { - if srcFlags.Has(jsonflags.Indent) { + dst.Flags.Join(src.Flags) + if src.Flags.Has(jsonflags.NonBooleanFlags) { + if src.Flags.Has(jsonflags.Indent) { dst.Indent = src.Indent } - if srcFlags.Has(jsonflags.IndentPrefix) { + if src.Flags.Has(jsonflags.IndentPrefix) { dst.IndentPrefix = src.IndentPrefix } - if srcFlags.Has(jsonflags.ByteLimit) { + if src.Flags.Has(jsonflags.ByteLimit) { dst.ByteLimit = src.ByteLimit } - if srcFlags.Has(jsonflags.DepthLimit) { + if src.Flags.Has(jsonflags.DepthLimit) { dst.DepthLimit = src.DepthLimit } - if srcFlags.Has(jsonflags.Marshalers) { + if src.Flags.Has(jsonflags.Marshalers) { dst.Marshalers = src.Marshalers } - if srcFlags.Has(jsonflags.Unmarshalers) { + if src.Flags.Has(jsonflags.Unmarshalers) { dst.Unmarshalers = src.Unmarshalers } + if src.Flags.Has(jsonflags.FormatTag) { + dst.Format = src.Format + } } default: *dst = JoinUnknownOption(*dst, src) @@ -187,6 +180,28 @@ func (dst *Struct) join(excludeCoderOptions bool, srcs ...Options) { } } +// InitializeMultiline sets default options implied by Multiline. +func (s *Struct) InitializeMultiline() { + if !s.Flags.Has(jsonflags.SpaceAfterColon) { + s.Flags.Set(jsonflags.SpaceAfterColon | 1) + } + if !s.Flags.Has(jsonflags.SpaceAfterComma) { + s.Flags.Set(jsonflags.SpaceAfterComma | 0) + } + if !s.Flags.Has(jsonflags.Indent) { + s.Flags.Set(jsonflags.Indent | 1) + s.Indent = "\t" + } +} + +// ChangedWhitespace reports whether whitespace values have changed. +func ChangedWhitespace(s1, s2 Struct) bool { + return s1.Flags.Get(jsonflags.Multiline) != s2.Flags.Get(jsonflags.Multiline) || + s1.Flags.Get(jsonflags.SpaceAfterColon) != s2.Flags.Get(jsonflags.SpaceAfterColon) || + s1.Flags.Get(jsonflags.SpaceAfterComma) != s2.Flags.Get(jsonflags.SpaceAfterComma) || + (s2.Flags.Get(jsonflags.Multiline) && (s1.Indent != s2.Indent || s1.IndentPrefix != s2.IndentPrefix)) +} + type ( Indent string // jsontext.WithIndent IndentPrefix string // jsontext.WithIndentPrefix diff --git a/vendor/github.com/go-json-experiment/json/internal/jsonopts/options_format.go b/vendor/github.com/go-json-experiment/json/internal/jsonopts/options_format.go new file mode 100644 index 0000000..283e05a --- /dev/null +++ b/vendor/github.com/go-json-experiment/json/internal/jsonopts/options_format.go @@ -0,0 +1,124 @@ +// Copyright 2026 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 !goexperiment.jsonv2 || !go1.25 + +package jsonopts + +// NOTE: While [ExperimentalSupportFormatTag] is exported, +// it is in an internal package and thus inaccessible for public use. +// +// The [github.com/go-json-experiment/json] module is kept in sync +// with the Go standard standard library and will expose this option +// in a way that public code can now directly reference. + +type supportFormatTag struct { + Options + v bool +} + +var ( + enableFormatTag = supportFormatTag{v: true} + disableFormatTag = supportFormatTag{v: false} +) + +// ExperimentalSupportFormatTag is a marker method that is specially +// recognized by the "github.com/go-json-experiment/json" runtime. +func (o *supportFormatTag) ExperimentalSupportFormatTag() bool { + return o.v +} + +// ExperimentalSupportFormatTag enables support for the `format` tag. +// +// WARNING: This is an experimental feature and will be removed in the future +// as either a failed experiment or be formally included in "github.com/go-json-experiment/json" +// in some semantically similar form, in which case, users of this option +// must migrate to the officially supported feature. +// +// The `format` tag was originally part of the "github.com/go-json-experiment/json" experiment +// but support for it was removed (see https://go.dev/issue/79071) for the +// initial release of "github.com/go-json-experiment/json" in light of the anticipation that +// the Go language might support typed struct tags (https://go.dev/issue/74472). +// +// Typed struct tags are a more expressive and type-safe way to express format +// attributes than the bespoke `format` tag option that implements a miniature +// domain-specific language (DSL) within the "json" package itself. +// +// While "github.com/go-json-experiment/json" was in the experimental phase, +// some users were already depending on the `format` tag option. +// This experimental option exists to provide a temporary workaround +// until the (hopeful) inclusion of typed struct tags and support for +// formatting directives in "github.com/go-json-experiment/json" using that language mechanism. +// +// This option enables support for the `format` tag option, which specifies +// a format flag used to specialize the formatting of the field value. +// The option is a key-value pair specified as "format:value" where +// the value must be either a literal consisting of letters and numbers +// (e.g., `format:RFC3339`) or a single-quoted string literal +// (e.g., `format:'2006-01-02'`). The interpretation of the format flag +// is determined by the struct field type. +// +// Go types with alternative representations are as follows: +// +// - A Go []byte or [N]byte is usually represented as a JSON string +// containing the binary value encoded using RFC 4648. +// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. +// If the format is "base64url", then this uses RFC 4648, section 5. +// If the format is "base32", then this uses RFC 4648, section 6. +// If the format is "base32hex", then this uses RFC 4648, section 7. +// If the format is "base16" or "hex", then this uses RFC 4648, section 8. +// If the format is "array", then the bytes value is represented as a JSON array +// where each element recursively uses the JSON representation of each byte. +// +// - A Go float is usually represented as a JSON number. +// If the format is "nonfinite", then NaN, +Inf, and -Inf are represented as +// the JSON strings "NaN", "Infinity", and "-Infinity", respectively. +// Without the use of this format, such string values result in a [SemanticError]. +// +// - A nil Go map is usually encoded using an empty JSON object. +// If the format is "emitnull", then a nil map is encoded as a JSON null. +// If the format is "emitempty", then a nil map is encoded as an empty JSON object, +// regardless of whether [FormatNilMapAsNull] is specified. +// +// - A nil Go slice is usually encoded using an empty JSON array. +// If the format is "emitnull", then a nil slice is encoded as a JSON null. +// If the format is "emitempty", then a nil slice is encoded as an empty JSON array, +// regardless of whether [FormatNilSliceAsNull] is specified. +// +// - A Go pointer usually uses the JSON representation of the underlying value. +// The format is forwarded to the marshaling and unmarshaling of the underlying type. +// +// - A Go [time.Time] is usually represented as a JSON string containing +// the timestamp formatted in RFC 3339 with nanosecond precision. +// If the format matches one of the format constants declared +// in the time package (e.g., RFC1123), then that format is used. +// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", +// then the timestamp is represented as a possibly fractional JSON number +// of the number of seconds (or milliseconds, microseconds, or nanoseconds) +// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. +// To avoid a fractional component when encoding, +// round the timestamp to the relevant unit. +// Otherwise if non-empty, the format is used as-is and +// encoded using [time.Time.Format] and +// decoded using [time.Time.Parse]. +// +// - A Go [time.Duration] usually has no default representation. +// If the format is "sec", "milli", "micro", or "nano", +// then the duration is represented as a possibly fractional JSON number +// of the number of seconds (or milliseconds, microseconds, or nanoseconds). +// To avoid a fractional component when encoding, +// round the duration to the relevant unit. +// If the format is "units", it is represented as a JSON string +// encoded using [time.Duration.String] and decoded using [time.ParseDuration] +// (e.g., "1h30m" for 1 hour 30 minutes). +// If the format is "iso8601", it is represented as a JSON string using the +// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) +// using only accurate units of hours, minutes, and seconds. +func ExperimentalSupportFormatTag(v bool) Options { + if v { + return &enableFormatTag + } else { + return &disableFormatTag + } +} diff --git a/vendor/github.com/go-json-experiment/json/internal/jsonwire/decode.go b/vendor/github.com/go-json-experiment/json/internal/jsonwire/decode.go index 6a5acb8..3be86a5 100644 --- a/vendor/github.com/go-json-experiment/json/internal/jsonwire/decode.go +++ b/vendor/github.com/go-json-experiment/json/internal/jsonwire/decode.go @@ -39,7 +39,7 @@ func ConsumeWhitespace(b []byte) (n int) { } // ConsumeNull consumes the next JSON null literal per RFC 7159, section 3. -// It returns 0 if it is invalid, in which case consumeLiteral should be used. +// It returns 0 if it is invalid, in which case ConsumeLiteral should be used. func ConsumeNull(b []byte) int { // NOTE: The arguments and logic are kept simple to keep this inlinable. const literal = "null" @@ -50,7 +50,7 @@ func ConsumeNull(b []byte) int { } // ConsumeFalse consumes the next JSON false literal per RFC 7159, section 3. -// It returns 0 if it is invalid, in which case consumeLiteral should be used. +// It returns 0 if it is invalid, in which case ConsumeLiteral should be used. func ConsumeFalse(b []byte) int { // NOTE: The arguments and logic are kept simple to keep this inlinable. const literal = "false" @@ -61,7 +61,7 @@ func ConsumeFalse(b []byte) int { } // ConsumeTrue consumes the next JSON true literal per RFC 7159, section 3. -// It returns 0 if it is invalid, in which case consumeLiteral should be used. +// It returns 0 if it is invalid, in which case ConsumeLiteral should be used. func ConsumeTrue(b []byte) int { // NOTE: The arguments and logic are kept simple to keep this inlinable. const literal = "true" @@ -88,7 +88,7 @@ func ConsumeLiteral(b []byte, lit string) (n int, err error) { // ConsumeSimpleString consumes the next JSON string per RFC 7159, section 7 // but is limited to the grammar for an ASCII string without escape sequences. // It returns 0 if it is invalid or more complicated than a simple string, -// in which case consumeString should be called. +// in which case [ConsumeString] should be called. // // It rejects '<', '>', and '&' for compatibility reasons since these were // always escaped in the v1 implementation. Thus, if this function reports @@ -118,7 +118,7 @@ func ConsumeString(flags *ValueFlags, b []byte, validateUTF8 bool) (n int, err e return ConsumeStringResumable(flags, b, 0, validateUTF8) } -// ConsumeStringResumable is identical to consumeString but supports resuming +// ConsumeStringResumable is identical to [ConsumeString] but supports resuming // from a previous call that returned io.ErrUnexpectedEOF. func ConsumeStringResumable(flags *ValueFlags, b []byte, resumeOffset int, validateUTF8 bool) (n int, err error) { // Consume the leading double quote. @@ -254,7 +254,7 @@ func ConsumeStringResumable(flags *ValueFlags, b []byte, resumeOffset int, valid // Any invalid UTF-8 within the string will be replaced with utf8.RuneError, // but the error will be specified as having encountered such an error. // The input must be an entire JSON string with no surrounding whitespace. -func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) (v []byte, err error) { +func AppendUnquote(dst, src []byte) (v []byte, err error) { dst = slices.Grow(dst, len(src)) // Consume the leading double quote. @@ -292,7 +292,7 @@ func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) (v []byte, er return dst, err } - switch r, rn := utf8.DecodeRuneInString(string(truncateMaxUTF8(src[n:]))); { + switch r, rn := utf8.DecodeRune(src[n:]); { // Handle UTF-8 encoded byte sequence. // Due to specialized handling of ASCII above, we know that // all normal sequences at this point must be 2 bytes or larger. @@ -364,7 +364,7 @@ func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) (v []byte, er // Handle invalid UTF-8. case r == utf8.RuneError: dst = append(dst, src[i:n]...) - if !utf8.FullRuneInString(string(truncateMaxUTF8(src[n:]))) { + if !utf8.FullRune(src[n:]) { return dst, io.ErrUnexpectedEOF } // NOTE: An unescaped string may be longer than the escaped string @@ -387,7 +387,7 @@ func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) (v []byte, er // hasEscapedUTF16Prefix reports whether b is possibly // the truncated prefix of a \uFFFF escape sequence. -func hasEscapedUTF16Prefix[Bytes ~[]byte | ~string](b Bytes, lowerSurrogateHalf bool) bool { +func hasEscapedUTF16Prefix(b []byte, lowerSurrogateHalf bool) bool { for i := range len(b) { switch c := b[i]; { case i == 0 && c != '\\': @@ -420,9 +420,9 @@ func UnquoteMayCopy(b []byte, isVerbatim bool) []byte { } // ConsumeSimpleNumber consumes the next JSON number per RFC 7159, section 6 -// but is limited to the grammar for a positive integer. +// but is limited to the grammar for a non-negative integer. // It returns 0 if it is invalid or more complicated than a simple integer, -// in which case consumeNumber should be called. +// in which case ConsumeNumber should be called. func ConsumeSimpleNumber(b []byte) (n int) { // NOTE: The arguments and logic are kept simple to keep this inlinable. if len(b) > 0 { @@ -467,7 +467,7 @@ func ConsumeNumber(b []byte) (n int, err error) { return n, err } -// ConsumeNumberResumable is identical to consumeNumber but supports resuming +// ConsumeNumberResumable is identical to ConsumeNumber but supports resuming // from a previous call that returned io.ErrUnexpectedEOF. func ConsumeNumberResumable(b []byte, resumeOffset int, state ConsumeNumberState) (n int, _ ConsumeNumberState, err error) { // Jump to the right state when resuming from a partial consumption. @@ -565,7 +565,7 @@ beforeExponent: // parseHexUint16 is similar to strconv.ParseUint, // but operates directly on []byte and is optimized for base-16. // See https://go.dev/issue/42429. -func parseHexUint16[Bytes ~[]byte | ~string](b Bytes) (v uint16, ok bool) { +func parseHexUint16(b []byte) (v uint16, ok bool) { if len(b) != 4 { return 0, false } @@ -604,26 +604,3 @@ func ParseUint(b []byte) (v uint64, ok bool) { } return v, true } - -// ParseFloat parses a floating point number according to the Go float grammar. -// Note that the JSON number grammar is a strict subset. -// -// If the number overflows the finite representation of a float, -// then we return MaxFloat since any finite value will always be infinitely -// more accurate at representing another finite value than an infinite value. -func ParseFloat(b []byte, bits int) (v float64, ok bool) { - fv, err := strconv.ParseFloat(string(b), bits) - if math.IsInf(fv, 0) { - switch { - case bits == 32 && math.IsInf(fv, +1): - fv = +math.MaxFloat32 - case bits == 64 && math.IsInf(fv, +1): - fv = +math.MaxFloat64 - case bits == 32 && math.IsInf(fv, -1): - fv = -math.MaxFloat32 - case bits == 64 && math.IsInf(fv, -1): - fv = -math.MaxFloat64 - } - } - return fv, err == nil -} diff --git a/vendor/github.com/go-json-experiment/json/internal/jsonwire/encode.go b/vendor/github.com/go-json-experiment/json/internal/jsonwire/encode.go index 2dc4bc6..9689577 100644 --- a/vendor/github.com/go-json-experiment/json/internal/jsonwire/encode.go +++ b/vendor/github.com/go-json-experiment/json/internal/jsonwire/encode.go @@ -32,7 +32,7 @@ var escapeASCII = [...]uint8{ // NeedEscape reports whether src needs escaping of any characters. // It conservatively assumes EscapeForHTML and EscapeForJS. // It reports true for inputs with invalid UTF-8. -func NeedEscape[Bytes ~[]byte | ~string](src Bytes) bool { +func NeedEscape(src []byte) bool { var i int for uint(len(src)) > uint(i) { if c := src[i]; c < utf8.RuneSelf { @@ -41,7 +41,7 @@ func NeedEscape[Bytes ~[]byte | ~string](src Bytes) bool { } i++ } else { - r, rn := utf8.DecodeRuneInString(string(truncateMaxUTF8(src[i:]))) + r, rn := utf8.DecodeRune(src[i:]) if r == utf8.RuneError || r == '\u2028' || r == '\u2029' { return true } @@ -62,7 +62,7 @@ func NeedEscape[Bytes ~[]byte | ~string](src Bytes) bool { // invalid bytes are replaced with the Unicode replacement character ('\ufffd'). // If no escape flags are set, then the shortest representable form is used, // which is also the canonical form for strings (RFC 8785, section 3.2.2.2). -func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes, flags *jsonflags.Flags) ([]byte, error) { +func AppendQuote(dst, src []byte, flags *jsonflags.Flags) ([]byte, error) { var i, n int var hasInvalidUTF8 bool dst = slices.Grow(dst, len(`"`)+len(src)+len(`"`)) @@ -82,7 +82,7 @@ func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes, flags *jsonflag } } else { // Handle multi-byte Unicode. - r, rn := utf8.DecodeRuneInString(string(truncateMaxUTF8(src[n:]))) + r, rn := utf8.DecodeRune(src[n:]) n += rn if r != utf8.RuneError && r != '\u2028' && r != '\u2029' { continue // no escaping possibly needed @@ -178,7 +178,7 @@ func ReformatString(dst, src []byte, flags *jsonflags.Flags) ([]byte, int, error } i++ } else { - r, rn := utf8.DecodeRune(truncateMaxUTF8(src[i:])) + r, rn := utf8.DecodeRune(src[i:]) if (r == '\u2028' || r == '\u2029') && flags.Get(jsonflags.EscapeForJS) { dst = append(dst, src[lastAppendIndex:i]...) dst = appendEscapedUnicode(dst, r) @@ -193,7 +193,7 @@ func ReformatString(dst, src []byte, flags *jsonflags.Flags) ([]byte, int, error // The input contains characters that might need escaping, // unnecessary escape sequences, or invalid UTF-8. // Perform a round-trip unquote and quote to properly reformat - // these sequences according the current flags. + // these sequences according to the current flags. b, _ := AppendUnquote(nil, src[:n]) dst, _ = AppendQuote(dst, b, flags) return dst, n, nil @@ -235,7 +235,7 @@ func AppendFloat(dst []byte, src float64, bits int) []byte { return dst } -// ReformatNumber consumes a JSON string from src and appends it to dst, +// ReformatNumber consumes a JSON number from src and appends it to dst, // canonicalizing it if specified. // It returns the appended output and the number of consumed input bytes. func ReformatNumber(dst, src []byte, flags *jsonflags.Flags) ([]byte, int, error) { diff --git a/vendor/github.com/go-json-experiment/json/internal/jsonwire/wire.go b/vendor/github.com/go-json-experiment/json/internal/jsonwire/wire.go index a0622c6..41654dd 100644 --- a/vendor/github.com/go-json-experiment/json/internal/jsonwire/wire.go +++ b/vendor/github.com/go-json-experiment/json/internal/jsonwire/wire.go @@ -17,7 +17,7 @@ import ( "unicode/utf8" ) -// TrimSuffixWhitespace trims JSON from the end of b. +// TrimSuffixWhitespace trims JSON whitespace from the end of b. func TrimSuffixWhitespace(b []byte) []byte { // NOTE: The arguments and logic are kept simple to keep this inlinable. n := len(b) - 1 @@ -59,8 +59,8 @@ func TrimSuffixByte(b []byte, c byte) []byte { } // QuoteRune quotes the first rune in the input. -func QuoteRune[Bytes ~[]byte | ~string](b Bytes) string { - r, n := utf8.DecodeRuneInString(string(truncateMaxUTF8(b))) +func QuoteRune(b []byte) string { + r, n := utf8.DecodeRune(b) if r == utf8.RuneError && n == 1 { return `'\x` + strconv.FormatUint(uint64(b[0]), 16) + `'` } @@ -70,7 +70,7 @@ func QuoteRune[Bytes ~[]byte | ~string](b Bytes) string { // CompareUTF16 lexicographically compares x to y according // to the UTF-16 codepoints of the UTF-8 encoded input strings. // This implements the ordering specified in RFC 8785, section 3.2.3. -func CompareUTF16[Bytes ~[]byte | ~string](x, y Bytes) int { +func CompareUTF16(x, y []byte) int { // NOTE: This is an optimized, mostly allocation-free implementation // of CompareUTF16Simple in wire_test.go. FuzzCompareUTF16 verifies that the // two implementations agree on the result of comparing any two strings. @@ -93,8 +93,8 @@ func CompareUTF16[Bytes ~[]byte | ~string](x, y Bytes) int { } // Decode next pair of runes as UTF-8. - rx, nx := utf8.DecodeRuneInString(string(truncateMaxUTF8(x))) - ry, ny := utf8.DecodeRuneInString(string(truncateMaxUTF8(y))) + rx, nx := utf8.DecodeRune(x) + ry, ny := utf8.DecodeRune(y) selfx := isUTF16Self(rx) selfy := isUTF16Self(ry) @@ -123,49 +123,41 @@ func CompareUTF16[Bytes ~[]byte | ~string](x, y Bytes) int { } } -// truncateMaxUTF8 truncates b such it contains at least one rune. -// -// The utf8 package currently lacks generic variants, which complicates -// generic functions that operates on either []byte or string. -// As a hack, we always call the utf8 function operating on strings, -// but always truncate the input such that the result is identical. -// -// Example usage: -// -// utf8.DecodeRuneInString(string(truncateMaxUTF8(b))) -// -// Converting a []byte to a string is stack allocated since -// truncateMaxUTF8 guarantees that the []byte is short. -func truncateMaxUTF8[Bytes ~[]byte | ~string](b Bytes) Bytes { - // TODO(https://go.dev/issue/56948): Remove this function and - // instead directly call generic utf8 functions wherever used. - if len(b) > utf8.UTFMax { - return b[:utf8.UTFMax] - } - return b -} - // TODO(https://go.dev/issue/70547): Use utf8.ErrInvalid instead. var ErrInvalidUTF8 = errors.New("invalid UTF-8") func NewInvalidCharacterError[Bytes ~[]byte | ~string](prefix Bytes, where string) error { - what := QuoteRune(prefix) - return errors.New("invalid character " + what + " " + where) + _, n := utf8.DecodeRune([]byte(prefix)) + return &InvalidTextError{"character", string(prefix[:n]), where} } func NewInvalidEscapeSequenceError[Bytes ~[]byte | ~string](what Bytes) error { - label := "escape sequence" if len(what) > 6 { - label = "surrogate pair" + return &InvalidTextError{"surrogate pair", string(what), "in string"} } - needEscape := strings.IndexFunc(string(what), func(r rune) bool { + return &InvalidTextError{"escape sequence", string(what), "in string"} +} + +type InvalidTextError struct { + Label string // e.g., "character" | "escape sequence" | "surrogate pair" + What string // raw invalid text + Where string // e.g., "in string" | "at start of value" +} + +func (e *InvalidTextError) Error() string { + var what string + needEscape := strings.ContainsFunc(e.What, func(r rune) bool { return r == '`' || r == utf8.RuneError || unicode.IsSpace(r) || !unicode.IsPrint(r) - }) >= 0 - if needEscape { - return errors.New("invalid " + label + " " + strconv.Quote(string(what)) + " in string") - } else { - return errors.New("invalid " + label + " `" + string(what) + "` in string") + }) + switch { + case utf8.RuneCount([]byte(e.What)) == 1: + what = QuoteRune([]byte(e.What)) + case needEscape: + what = strconv.Quote(e.What) + default: + what = "`" + e.What + "`" } + return strings.TrimSuffix("invalid "+e.Label+" "+what+" "+e.Where, " ") } // TruncatePointer optionally truncates the JSON pointer, diff --git a/vendor/github.com/go-json-experiment/json/jsontext/alias.go b/vendor/github.com/go-json-experiment/json/jsontext/alias.go index dc18d5d..c5a6867 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/alias.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/alias.go @@ -36,7 +36,7 @@ // // - a JSON literal, string, or number // - a JSON object (e.g., `{"name":"value"}`) -// - a JSON array (e.g., `[1,2,3,]`) +// - a JSON array (e.g., `[1,2,3]`) // // A JSON value is represented by the [Value] type in Go and is a []byte // containing the raw textual representation of the value. There is some overlap @@ -45,18 +45,18 @@ // // The [Encoder] and [Decoder] types contain methods to read or write the next // [Token] or [Value] in a sequence. They maintain a state machine to validate -// whether the sequence of JSON tokens and/or values produces a valid JSON. +// whether the sequence of JSON tokens and/or values produces valid JSON. // [Options] may be passed to the [NewEncoder] or [NewDecoder] constructors -// to configure the syntactic behavior of encoding and decoding. +// to configure the behavior of encoding and decoding. // // # Terminology // // The terms "encode" and "decode" are used for syntactic functionality // that is concerned with processing JSON based on its grammar, and // the terms "marshal" and "unmarshal" are used for semantic functionality -// that determines the meaning of JSON values as Go values and vice-versa. -// This package (i.e., [jsontext]) deals with JSON at a syntactic layer, -// while [encoding/json/v2] deals with JSON at a semantic layer. +// that determines the meaning of JSON values as Go values and vice versa. +// This package deals with JSON syntax, +// while [encoding/json/v2] deals with JSON semantics. // The goal is to provide a clear distinction between functionality that // is purely concerned with encoding versus that of marshaling. // For example, one can directly encode a stream of JSON tokens without @@ -136,7 +136,7 @@ import ( // d.ReadValue() // {"k":"v"} // d.ReadToken() // } // -// The above is one of many possible sequence of calls and +// The above is one of many possible sequences of calls and // may not represent the most sensible method to call for any given token/value. // For example, it is probably more common to call [Decoder.ReadToken] to obtain a // string token for object names. @@ -151,7 +151,7 @@ func NewDecoder(r io.Reader, opts ...Options) *Decoder { return jsontext.NewDecoder(r, opts...) } -// Encoder is a streaming encoder from raw JSON tokens and values. +// Encoder is a streaming encoder to raw JSON tokens and values. // It is used to write a stream of top-level JSON values, // each terminated with a newline character. // @@ -176,7 +176,7 @@ func NewDecoder(r io.Reader, opts ...Options) *Decoder { // e.WriteValue(Value(`{"k":"v"}`)) // {"k":"v"} // e.WriteToken(EndObject) // } // -// The above is one of many possible sequence of calls and +// The above is one of many possible sequences of calls and // may not represent the most sensible method to call for any given token/value. // For example, it is probably more common to call [Encoder.WriteToken] with a string // for object names. @@ -193,7 +193,7 @@ func NewEncoder(w io.Writer, opts ...Options) *Encoder { return jsontext.NewEncoder(w, opts...) } -// SyntacticError is a description of a syntactic error that occurred when +// SyntacticError is a description of an error that occurred when // encoding or decoding JSON according to the grammar. // // The contents of this error as produced by this package may change over time. @@ -202,7 +202,7 @@ type SyntacticError = jsontext.SyntacticError // Options configures [NewEncoder], [Encoder.Reset], [NewDecoder], // and [Decoder.Reset] with specific features. // Each function takes in a variadic list of options, where properties -// set in latter options override the value of previously set properties. +// set in later options override the value of previously set properties. // // There is a single Options type, which is used with both encoding and decoding. // Some options affect both operations, while others only affect one operation: @@ -308,7 +308,7 @@ func CanonicalizeRawInts(v bool) Options { // It is safe to canonicalize a serialized single precision number and // parse it back as a single precision number and expect the same value. // If a number exceeds ±1.7976931348623157e+308, which is the maximum -// finite number, then it saturated at that value and formatted as such. +// finite number, then it is saturated at that value and formatted as such. // // This only affects encoding and is ignored when decoding. func CanonicalizeRawFloats(v bool) Options { @@ -350,7 +350,7 @@ func SpaceAfterComma(v bool) Options { // If [SpaceAfterComma] is not specified, then the default is false. // If [WithIndent] is not specified, then the default is "\t". // -// If set to false, then the output is a single-line, +// If set to false, then the output is a single line, // where the only whitespace emitted is determined by the current // values of [SpaceAfterColon] and [SpaceAfterComma]. // @@ -363,9 +363,9 @@ func Multiline(v bool) Options { // where each element in a JSON object or array begins on a new, indented line // beginning with the indent prefix (see [WithIndentPrefix]) // followed by one or more copies of indent according to the nesting depth. -// The indent must only be composed of space or tab characters. +// The indent must be composed of only space and tab characters. // -// If the intent to emit indented output without a preference for +// If the intent is to emit indented output without a preference for // the particular indent string, then use [Multiline] instead. // // This only affects encoding and is ignored when decoding. @@ -378,7 +378,7 @@ func WithIndent(indent string) Options { // where each element in a JSON object or array begins on a new, indented line // beginning with the indent prefix followed by one or more copies of indent // (see [WithIndent]) according to the nesting depth. -// The prefix must only be composed of space or tab characters. +// The prefix must be composed of only space and tab characters. // // This only affects encoding and is ignored when decoding. // Use of this option implies [Multiline] being set to true. @@ -414,8 +414,8 @@ func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, erro // The name of a duplicate JSON object member can be extracted as: // // err := ... -// var serr jsontext.SyntacticError -// if errors.As(err, &serr) && serr.Err == jsontext.ErrDuplicateName { +// serr, ok := errors.AsType[*jsontext.SyntacticError](err) +// if ok && serr.Err == jsontext.ErrDuplicateName { // ptr := serr.JSONPointer // JSON pointer to duplicate name // name := ptr.LastToken() // duplicate name itself // ... @@ -437,12 +437,12 @@ var ErrNonStringName = jsontext.ErrNonStringName // either a JSON object name or an index to a JSON array element // encoded as a base-10 integer value. // It is impossible to distinguish between an array index and an object name -// (that happens to be an base-10 encoded integer) without also knowing +// (that happens to be a base-10 encoded integer) without also knowing // the structure of the top-level JSON value that the pointer refers to. // // There is exactly one representation of a pointer to a particular value, // so comparability of Pointer values is equivalent to checking whether -// they both point to the exact same value. +// they both point to the same value. type Pointer = jsontext.Pointer // Token represents a lexical JSON token, which may be one of the following: @@ -455,6 +455,20 @@ type Pointer = jsontext.Pointer // A Token cannot represent entire array or object values, while a [Value] can. // There is no Token to represent commas and colons since // these structural tokens can be inferred from the surrounding context. +// +// A Token stores data in one of two forms: +// +// - As raw JSON text: backed by the internal buffer of the [Decoder] +// and only ever produced by [Decoder.ReadToken]. +// Such a token is only valid until the next call to any method on that +// [Decoder] (e.g., [Decoder.PeekKind], [Decoder.ReadToken], +// [Decoder.ReadValue], or [Decoder.SkipValue]). +// Call [Token.Clone] to copy the raw text into an independent allocation +// that persists beyond subsequent [Decoder] calls. +// +// - As a typed Go value: a self-contained representation produced by +// the constructor functions (e.g., [String], [Int], [Uint], [Float]). +// Such tokens are valid indefinitely and do not need to be cloned. type Token = jsontext.Token var ( @@ -479,7 +493,10 @@ func String(s string) Token { return jsontext.String(s) } -// Float constructs a Token representing a JSON number. +// Float constructs a Token representing a JSON number as +// a 64-bit floating-point number formatted according to +// ECMA-262, 10th edition, section 7.1.12.1 and RFC 8785, section 3.2.2.3. +// with the exception that -0 is still formatted as -0. // The values NaN, +Inf, and -Inf will be represented // as a JSON string with the values "NaN", "Infinity", and "-Infinity". func Float(n float64) Token { @@ -496,32 +513,34 @@ func Uint(n uint64) Token { return jsontext.Uint(n) } -// Kind represents each possible JSON token kind with a single byte, -// which is conveniently the first byte of that kind's grammar -// with the restriction that numbers always be represented with '0': +// A Kind represents the kind of a JSON token. // -// - 'n': null -// - 'f': false -// - 't': true -// - '"': string -// - '0': number -// - '{': object begin -// - '}': object end -// - '[': array begin -// - ']': array end -// -// An invalid kind is usually represented using 0, -// but may be non-zero due to invalid JSON data. +// A Kind is a single byte, which is conveniently the first byte of that +// kind's symbol in the grammar (except for numbers, which are always represented +// with '0'). type Kind = jsontext.Kind +const ( + KindInvalid = jsontext.KindInvalid + KindNull = jsontext.KindNull + KindFalse = jsontext.KindFalse + KindTrue = jsontext.KindTrue + KindString = jsontext.KindString + KindNumber = jsontext.KindNumber + KindBeginObject = jsontext.KindBeginObject + KindEndObject = jsontext.KindEndObject + KindBeginArray = jsontext.KindBeginArray + KindEndArray = jsontext.KindEndArray +) + // AppendFormat formats the JSON value in src and appends it to dst // according to the specified options. // See [Value.Format] for more details about the formatting behavior. // // The dst and src may overlap. // If an error is reported, then the entirety of src is appended to dst. -func AppendFormat(dst, src []byte, opts ...Options) ([]byte, error) { - return jsontext.AppendFormat(dst, src, opts...) +func AppendFormat[Bytes ~[]byte | ~string](dst []byte, src Bytes, opts ...Options) ([]byte, error) { + return jsontext.AppendFormat(dst, []byte(src), opts...) } // Value represents a single raw JSON value, which may be one of the following: diff --git a/vendor/github.com/go-json-experiment/json/jsontext/decode.go b/vendor/github.com/go-json-experiment/json/jsontext/decode.go index 9326ace..7f00bb0 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/decode.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/decode.go @@ -34,11 +34,11 @@ import ( // return the end of the consumed JSON token as a position, // also relative to the start of Decoder.buf. // -// - In the event of an I/O errors or state machine violations, +// - In the event of an I/O error or state machine violations, // the implementation avoids mutating the state of Decoder // (aside from the book-keeping needed to implement Decoder.fetch). // For this reason, only Decoder.ReadToken and Decoder.ReadValue are -// responsible for updated Decoder.prevStart and Decoder.prevEnd. +// responsible for updating Decoder.prevStart and Decoder.prevEnd. // // - For performance, much of the implementation uses the pattern of calling // the inlinable consumeXXX functions first, and if more work is necessary, @@ -71,7 +71,7 @@ import ( // d.ReadValue() // {"k":"v"} // d.ReadToken() // } // -// The above is one of many possible sequence of calls and +// The above is one of many possible sequences of calls and // may not represent the most sensible method to call for any given token/value. // For example, it is probably more common to call [Decoder.ReadToken] to obtain a // string token for object names. @@ -80,7 +80,7 @@ type Decoder struct { } // decoderState is the low-level state of Decoder. -// It has exported fields and method for use by the "json" package. +// It has exported fields and methods for use by the "json" package. type decoderState struct { state decodeBuffer @@ -126,7 +126,7 @@ func NewDecoder(r io.Reader, opts ...Options) *Decoder { } // Reset resets a decoder such that it is reading afresh from r and -// configured with the provided options. Reset must not be called on an +// configured with the provided options. Reset must not be called on // a Decoder passed to the [encoding/json/v2.UnmarshalerFrom.UnmarshalJSONFrom] method // or the [encoding/json/v2.UnmarshalFromFunc] function. func (d *Decoder) Reset(r io.Reader, opts ...Options) { @@ -154,7 +154,7 @@ func (d *decoderState) reset(b []byte, r io.Reader, opts ...Options) { d.Struct = opts2 } -// Options returns the options used to construct the encoder and +// Options returns the options used to construct the decoder and // may additionally contain semantic options passed to a // [encoding/json/v2.UnmarshalDecode] call. // @@ -166,6 +166,8 @@ func (d *Decoder) Options() Options { return &d.s.Struct } +func (d *decoderState) options() *jsonopts.Struct { return &d.Struct } + var errBufferWriteAfterNext = errors.New("invalid bytes.Buffer.Write call after calling bytes.Buffer.Next") // fetch reads at least 1 byte from the underlying io.Reader. @@ -193,7 +195,7 @@ func (d *decoderState) fetch() error { // may overwrite the contents of the current buffer. // // The user is trying to use a bytes.Buffer as a pipe, - // but a bytes.Buffer is poor implementation of a pipe, + // but a bytes.Buffer is a poor implementation of a pipe, // the purpose-built io.Pipe should be used instead. return &ioError{action: "read", err: errBufferWriteAfterNext} } @@ -306,7 +308,7 @@ func (d *decodeBuffer) PreviousTokenOrValue() []byte { // PeekKind retrieves the next token kind, but does not advance the read offset. // -// It returns 0 if an error occurs. Any such error is cached until +// It returns [KindInvalid] if an error occurs. Any such error is cached until // the next read call and it is the caller's responsibility to eventually // follow up a PeekKind call with a read call. func (d *Decoder) PeekKind() Kind { @@ -407,10 +409,11 @@ func (d *decoderState) checkDelim(delim byte, next Kind) error { } // SkipValue is semantically equivalent to calling [Decoder.ReadValue] and discarding -// the result except that memory is not wasted trying to hold the entire result. +// the result, except that memory is not wasted trying to hold the entire result. func (d *Decoder) SkipValue() error { return d.s.SkipValue() } + func (d *decoderState) SkipValue() error { switch d.PeekKind() { case '{', '[': @@ -621,6 +624,7 @@ func (d *decoderState) ReadToken() (Token, error) { if !d.Flags.Get(jsonflags.AllowDuplicateNames) { d.Namespaces.push() } + d.Flags.Clear(jsonflags.TagFlags) // tags only apply to current depth pos += 1 d.prevStart, d.prevEnd = pos, pos return BeginObject, nil @@ -641,6 +645,7 @@ func (d *decoderState) ReadToken() (Token, error) { if err = d.Tokens.pushArray(); err != nil { return Token{}, wrapSyntacticError(d, err, pos, +1) } + d.Flags.Clear(jsonflags.TagFlags) // tags only apply to current depth pos += 1 d.prevStart, d.prevEnd = pos, pos return BeginArray, nil @@ -792,6 +797,12 @@ func (d *decoderState) CheckNextValue(last bool) error { return nil } +// AtEOF reports whether the decoder is at EOF. +func (d *decoderState) AtEOF() bool { + _, err := d.consumeWhitespace(d.prevEnd) + return err == io.ErrUnexpectedEOF +} + // CheckEOF verifies that the input has no more data. func (d *decoderState) CheckEOF() error { return d.checkEOF(d.prevEnd) @@ -1121,24 +1132,54 @@ func (d *decoderState) consumeArray(flags *jsonwire.ValueFlags, pos, depth int) // InputOffset returns the current input byte offset. It gives the location // of the next byte immediately after the most recently returned token or value. // The number of bytes actually read from the underlying [io.Reader] may be more -// than this offset due to internal buffering effects. +// than this offset due to internal buffering. func (d *Decoder) InputOffset() int64 { return d.s.previousOffsetEnd() } // UnreadBuffer returns the data remaining in the unread buffer, // which may contain zero or more bytes. +// This is the data already consumed from the input [io.Reader], +// but not yet read by a [Decoder.ReadToken] or [Decoder.ReadValue] call. +// It may contain bytes that do not form valid JSON, since it has not yet +// been validated according to the JSON grammar. +// The exact amount of buffered data is an implementation detail +// of the Decoder and may change over time. +// +// It is the caller's responsibility to concatenate this buffer with +// the remainder of the input Reader to obtain the full sequence +// of bytes after the last read JSON token or value. +// // The returned buffer must not be mutated while Decoder continues to be used. // The buffer contents are valid until the next Peek, Read, or Skip call. func (d *Decoder) UnreadBuffer() []byte { return d.s.unreadBuffer() } -// StackDepth returns the depth of the state machine for read JSON data. +// StackDepth returns the depth of the state machine for JSON data +// that has already been read. // Each level on the stack represents a nested JSON object or array. -// It is incremented whenever an [BeginObject] or [BeginArray] token is encountered +// It is incremented whenever a [BeginObject] or [BeginArray] token is encountered // and decremented whenever an [EndObject] or [EndArray] token is encountered. -// The depth is zero-indexed, where zero represents the top-level JSON value. +// +// StackDepth returns 0 when not inside any object or array. +// In particular, it returns 0 before any tokens have been read, +// after any top-level value has been read, and between values +// when decoding a stream of top-level values (e.g., NDJSON). +// StackDepth returns 1 inside a top-level object or array, +// 2 inside a nested object or array, and so on. +// +// For example, consider decoding the following JSON: +// +// {"a": [1, 2], "b": {"c": 3}} +// +// While decoding, StackDepth would report the following: +// +// - At the start, StackDepth reports 0. +// - After decoding the outer '{', StackDepth reports 1. +// - After decoding the inner '[', StackDepth reports 2. +// - After decoding the inner ']', StackDepth reports 1. +// - After decoding the outer '}', StackDepth reports 0. func (d *Decoder) StackDepth() int { // NOTE: Keep in sync with Encoder.StackDepth. return d.s.Tokens.Depth() - 1 @@ -1148,13 +1189,13 @@ func (d *Decoder) StackDepth() int { // It must be a number between 0 and [Decoder.StackDepth], inclusive. // For each level, it reports the kind: // -// - 0 for a level of zero, -// - '{' for a level representing a JSON object, and -// - '[' for a level representing a JSON array. +// - [KindInvalid] for a level of zero, +// - [KindBeginObject] for a level representing a JSON object, and +// - [KindBeginArray] for a level representing a JSON array. // -// It also reports the length of that JSON object or array. +// It also reports the length of that JSON object or array decoded so far. // Each name and value in a JSON object is counted separately, -// so the effective number of members would be half the length. +// so the effective number of members is half the length. // A complete JSON object must have an even length. func (d *Decoder) StackIndex(i int) (Kind, int64) { // NOTE: Keep in sync with Encoder.StackIndex. diff --git a/vendor/github.com/go-json-experiment/json/jsontext/doc.go b/vendor/github.com/go-json-experiment/json/jsontext/doc.go index 22081df..2515be3 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/doc.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/doc.go @@ -34,7 +34,7 @@ // // - a JSON literal, string, or number // - a JSON object (e.g., `{"name":"value"}`) -// - a JSON array (e.g., `[1,2,3,]`) +// - a JSON array (e.g., `[1,2,3]`) // // A JSON value is represented by the [Value] type in Go and is a []byte // containing the raw textual representation of the value. There is some overlap @@ -43,18 +43,18 @@ // // The [Encoder] and [Decoder] types contain methods to read or write the next // [Token] or [Value] in a sequence. They maintain a state machine to validate -// whether the sequence of JSON tokens and/or values produces a valid JSON. +// whether the sequence of JSON tokens and/or values produces valid JSON. // [Options] may be passed to the [NewEncoder] or [NewDecoder] constructors -// to configure the syntactic behavior of encoding and decoding. +// to configure the behavior of encoding and decoding. // // # Terminology // // The terms "encode" and "decode" are used for syntactic functionality // that is concerned with processing JSON based on its grammar, and // the terms "marshal" and "unmarshal" are used for semantic functionality -// that determines the meaning of JSON values as Go values and vice-versa. -// This package (i.e., [jsontext]) deals with JSON at a syntactic layer, -// while [encoding/json/v2] deals with JSON at a semantic layer. +// that determines the meaning of JSON values as Go values and vice versa. +// This package deals with JSON syntax, +// while [encoding/json/v2] deals with JSON semantics. // The goal is to provide a clear distinction between functionality that // is purely concerned with encoding versus that of marshaling. // For example, one can directly encode a stream of JSON tokens without diff --git a/vendor/github.com/go-json-experiment/json/jsontext/encode.go b/vendor/github.com/go-json-experiment/json/jsontext/encode.go index 1108203..bb16923 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/encode.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/encode.go @@ -16,7 +16,7 @@ import ( "github.com/go-json-experiment/json/internal/jsonwire" ) -// Encoder is a streaming encoder from raw JSON tokens and values. +// Encoder is a streaming encoder to raw JSON tokens and values. // It is used to write a stream of top-level JSON values, // each terminated with a newline character. // @@ -41,7 +41,7 @@ import ( // e.WriteValue(Value(`{"k":"v"}`)) // {"k":"v"} // e.WriteToken(EndObject) // } // -// The above is one of many possible sequence of calls and +// The above is one of many possible sequences of calls and // may not represent the most sensible method to call for any given token/value. // For example, it is probably more common to call [Encoder.WriteToken] with a string // for object names. @@ -50,7 +50,7 @@ type Encoder struct { } // encoderState is the low-level state of Encoder. -// It has exported fields and method for use by the "json" package. +// It has exported fields and methods for use by the "json" package. type encoderState struct { state encodeBuffer @@ -96,7 +96,7 @@ func NewEncoder(w io.Writer, opts ...Options) *Encoder { // Reset resets an encoder such that it is writing afresh to w and // configured with the provided options. Reset must not be called on -// a Encoder passed to the [encoding/json/v2.MarshalerTo.MarshalJSONTo] method +// an Encoder passed to the [encoding/json/v2.MarshalerTo.MarshalJSONTo] method // or the [encoding/json/v2.MarshalToFunc] function. func (e *Encoder) Reset(w io.Writer, opts ...Options) { switch { @@ -124,21 +124,12 @@ func (e *encoderState) reset(b []byte, w io.Writer, opts ...Options) { opts2 := jsonopts.Struct{} // avoid mutating e.Struct in case it is part of opts opts2.Join(opts...) e.Struct = opts2 - if e.Flags.Get(jsonflags.Multiline) { - if !e.Flags.Has(jsonflags.SpaceAfterColon) { - e.Flags.Set(jsonflags.SpaceAfterColon | 1) - } - if !e.Flags.Has(jsonflags.SpaceAfterComma) { - e.Flags.Set(jsonflags.SpaceAfterComma | 0) - } - if !e.Flags.Has(jsonflags.Indent) { - e.Flags.Set(jsonflags.Indent | 1) - e.Indent = "\t" - } + if e.Struct.Flags.Get(jsonflags.Multiline) { + e.Struct.InitializeMultiline() } } -// Options returns the options used to construct the decoder and +// Options returns the options used to construct the encoder and // may additionally contain semantic options passed to a // [encoding/json/v2.MarshalEncode] call. // @@ -150,6 +141,8 @@ func (e *Encoder) Options() Options { return &e.s.Struct } +func (e *encoderState) options() *jsonopts.Struct { return &e.Struct } + // NeedFlush determines whether to flush at this point. func (e *encoderState) NeedFlush() bool { // NOTE: This function is carefully written to be inlinable. @@ -178,7 +171,7 @@ func (e *encoderState) Flush() error { // Specialize bytes.Buffer for better performance. if bb, ok := e.wr.(*bytes.Buffer); ok { - // If e.buf already aliases the internal buffer of bb, + // If e.Buf already aliases the internal buffer of bb, // then the Write call simply increments the internal offset, // otherwise Write operates as expected. // See https://go.dev/issue/42986. @@ -213,7 +206,7 @@ func (e *encoderState) Flush() error { e.Buf = e.Buf[:0] // Check whether to grow the buffer. - // Note that cap(e.buf) may already exceed maxBufferSize since + // Note that cap(e.Buf) may already exceed maxBufferSize since // an append elsewhere already grew it to store a large token. const maxBufferSize = 4 << 10 const growthSizeFactor = 2 // higher value is faster @@ -229,7 +222,7 @@ func (e *encoderState) Flush() error { return nil } -func (d *encodeBuffer) offsetAt(pos int) int64 { return d.baseOffset + int64(pos) } +func (e *encodeBuffer) offsetAt(pos int) int64 { return e.baseOffset + int64(pos) } func (e *encodeBuffer) previousOffsetEnd() int64 { return e.baseOffset + int64(len(e.Buf)) } func (e *encodeBuffer) unflushedBuffer() []byte { return e.Buf } @@ -344,9 +337,10 @@ func (e *encoderState) UnwriteOnlyObjectMemberName() string { // For example, it is an error to provide a number when the encoder // is expecting an object name (which is always a string), or // to provide an end object delimiter when the encoder is finishing an array. -// If the provided token is invalid, then it reports a [SyntacticError] and +// If the provided token is invalid, then WriteToken reports a [SyntacticError] and // the internal state remains unchanged. The offset reported -// in [SyntacticError] will be relative to the [Encoder.OutputOffset]. +// in [SyntacticError] will be the [Encoder.OutputOffset] plus any delimiter +// or whitespace characters that would have preceded the provided token. func (e *Encoder) WriteToken(t Token) error { return e.s.WriteToken(t) } @@ -405,6 +399,7 @@ func (e *encoderState) WriteToken(t Token) error { if !e.Flags.Get(jsonflags.AllowDuplicateNames) { e.Namespaces.push() } + e.Flags.Clear(jsonflags.TagFlags) // tags only apply to current depth case '}': b = append(b, '}') if err = e.Tokens.popObject(); err != nil { @@ -417,6 +412,7 @@ func (e *encoderState) WriteToken(t Token) error { case '[': b = append(b, '[') err = e.Tokens.pushArray() + e.Flags.Clear(jsonflags.TagFlags) // tags only apply to current depth case ']': b = append(b, ']') err = e.Tokens.popArray() @@ -471,7 +467,7 @@ func (e *encoderState) AppendRaw(k Kind, safeASCII bool, appendFn func([]byte) ( if !isVerbatim { var err error b2 := append(e.availBuffer, b[pos+len(`"`):len(b)-len(`"`)]...) - b, err = jsonwire.AppendQuote(b[:pos], string(b2), &e.Flags) + b, err = jsonwire.AppendQuote(b[:pos], b2, &e.Flags) e.availBuffer = b2[:0] if err != nil { return wrapSyntacticError(e, err, pos, +1) @@ -482,7 +478,7 @@ func (e *encoderState) AppendRaw(k Kind, safeASCII bool, appendFn func([]byte) ( if e.Tokens.Last.NeedObjectName() { if !e.Flags.Get(jsonflags.AllowDuplicateNames) { if !e.Tokens.Last.isValidNamespace() { - return wrapSyntacticError(e, err, pos, +1) + return wrapSyntacticError(e, errInvalidNamespace, pos, +1) } if e.Tokens.Last.isActiveNamespace() && !e.Namespaces.Last().insertQuoted(b[pos:], isVerbatim) { err = wrapWithObjectName(ErrDuplicateName, b[pos:]) @@ -522,9 +518,9 @@ func (e *encoderState) AppendRaw(k Kind, safeASCII bool, appendFn func([]byte) ( // // The provided value kind must be consistent with the JSON grammar // (see examples on [Encoder.WriteToken]). If the provided value is invalid, -// then it reports a [SyntacticError] and the internal state remains unchanged. -// The offset reported in [SyntacticError] will be relative to the -// [Encoder.OutputOffset] plus the offset into v of any encountered syntax error. +// then WriteValue reports a [SyntacticError] and the internal state remains unchanged. +// The offset reported in [SyntacticError] will be the [Encoder.OutputOffset] +// plus the offset into v of any encountered syntax error. func (e *Encoder) WriteValue(v Value) error { return e.s.WriteValue(v) } @@ -541,7 +537,7 @@ func (e *encoderState) WriteValue(v Value) error { } pos := len(b) // offset before the value - // Append the value the output. + // Append the value to the output. var n int n += jsonwire.ConsumeWhitespace(v[n:]) b, m, err := e.reformatValue(b, v[n:], e.Tokens.Depth()) @@ -715,7 +711,7 @@ func (e *encoderState) reformatValue(dst []byte, src Value, depth int) ([]byte, } // reformatObject parses a JSON object from the start of src and -// appends it to the end of src, reformatting whitespace and strings as needed. +// appends it to the end of dst, reformatting whitespace and strings as needed. // It returns the extended dst buffer and the number of consumed input bytes. func (e *encoderState) reformatObject(dst []byte, src Value, depth int) ([]byte, int, error) { // Append object begin. @@ -900,7 +896,7 @@ func (e *encoderState) reformatArray(dst []byte, src Value, depth int) ([]byte, // OutputOffset returns the current output byte offset. It gives the location // of the next byte immediately after the most recently written token or value. // The number of bytes actually written to the underlying [io.Writer] may be less -// than this offset due to internal buffering effects. +// than this offset due to internal buffering. func (e *Encoder) OutputOffset() int64 { return e.s.previousOffsetEnd() } @@ -911,19 +907,21 @@ func (e *Encoder) OutputOffset() int64 { // // Example usage: // -// b := d.AvailableBuffer() +// b := e.AvailableBuffer() // b = append(b, '"') // b = appendString(b, v) // append the string formatting of v // b = append(b, '"') -// ... := d.WriteValue(b) +// ... := e.WriteValue(b) // -// It is the user's responsibility to ensure that the value is valid JSON. +// Note that WriteValue expects a valid JSON value. Constructing a value in a +// raw []byte requires more care than using constructor functions like +// [String], which always return valid [Token]s or [Value]s. func (e *Encoder) AvailableBuffer() []byte { - // NOTE: We don't return e.buf[len(e.buf):cap(e.buf)] since WriteValue would + // NOTE: We don't return e.Buf[len(e.Buf):cap(e.Buf)] since WriteValue would // need to take special care to avoid mangling the data while reformatting. - // WriteValue can't easily identify whether the input Value aliases e.buf + // WriteValue can't easily identify whether the input Value aliases e.Buf // without using unsafe.Pointer. Thus, we just return a different buffer. - // Should this ever alias e.buf, we need to consider how it operates with + // Should this ever alias e.Buf, we need to consider how it operates with // the specialized performance optimization for bytes.Buffer. n := 1 << bits.Len(uint(e.s.maxValue|63)) // fast approximation for max length if cap(e.s.availBuffer) < n { @@ -934,9 +932,27 @@ func (e *Encoder) AvailableBuffer() []byte { // StackDepth returns the depth of the state machine for written JSON data. // Each level on the stack represents a nested JSON object or array. -// It is incremented whenever an [BeginObject] or [BeginArray] token is encountered +// It is incremented whenever a [BeginObject] or [BeginArray] token is encountered // and decremented whenever an [EndObject] or [EndArray] token is encountered. -// The depth is zero-indexed, where zero represents the top-level JSON value. +// +// StackDepth returns 0 when not inside any object or array. +// In particular, it returns 0 before any tokens have been written, +// after any top-level value has been written, and between values +// when encoding a stream of top-level values (e.g., NDJSON). +// StackDepth returns 1 inside a top-level object or array, +// 2 inside a nested object or array, and so on. +// +// For example, consider encoding the following JSON: +// +// {"a": [1, 2], "b": {"c": 3}} +// +// While encoding, StackDepth would report the following: +// +// - At the start, StackDepth reports 0. +// - After encoding the outer '{', StackDepth reports 1. +// - After encoding the inner '[', StackDepth reports 2. +// - After encoding the inner ']', StackDepth reports 1. +// - After encoding the outer '}', StackDepth reports 0. func (e *Encoder) StackDepth() int { // NOTE: Keep in sync with Decoder.StackDepth. return e.s.Tokens.Depth() - 1 @@ -946,13 +962,13 @@ func (e *Encoder) StackDepth() int { // It must be a number between 0 and [Encoder.StackDepth], inclusive. // For each level, it reports the kind: // -// - 0 for a level of zero, -// - '{' for a level representing a JSON object, and -// - '[' for a level representing a JSON array. +// - [KindInvalid] for a level of zero, +// - [KindBeginObject] for a level representing a JSON object, and +// - [KindBeginArray] for a level representing a JSON array. // -// It also reports the length of that JSON object or array. +// It also reports the length of that JSON object or array encoded so far. // Each name and value in a JSON object is counted separately, -// so the effective number of members would be half the length. +// so the effective number of members is half the length. // A complete JSON object must have an even length. func (e *Encoder) StackIndex(i int) (Kind, int64) { // NOTE: Keep in sync with Decoder.StackIndex. diff --git a/vendor/github.com/go-json-experiment/json/jsontext/errors.go b/vendor/github.com/go-json-experiment/json/jsontext/errors.go index 5ce906f..360417a 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/errors.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/errors.go @@ -11,6 +11,8 @@ import ( "io" "strconv" + "github.com/go-json-experiment/json/internal/jsonflags" + "github.com/go-json-experiment/json/internal/jsonopts" "github.com/go-json-experiment/json/internal/jsonwire" ) @@ -28,7 +30,20 @@ func (e *ioError) Unwrap() error { return e.err } -// SyntacticError is a description of a syntactic error that occurred when +type numError struct { + accessor string // either "Int", "Uint", or "Float" + value string // e.g., "1e1000" + err error // either [strconv.ErrSyntax] or [strconv.ErrRange] +} + +func (e *numError) Error() string { + return "jsontext.Token(" + e.value + ")." + e.accessor + " error: " + e.err.Error() +} +func (e *numError) Unwrap() error { + return e.err +} + +// SyntacticError is a description of an error that occurred when // encoding or decoding JSON according to the grammar. // // The contents of this error as produced by this package may change over time. @@ -36,7 +51,7 @@ type SyntacticError struct { requireKeyedLiterals nonComparable - // ByteOffset indicates that an error occurred after this byte offset. + // ByteOffset indicates that an error occurred at or after this byte offset. ByteOffset int64 // JSONPointer indicates that an error occurred within this JSON value // as indicated using the JSON Pointer notation (see RFC 6901). @@ -53,10 +68,11 @@ type SyntacticError struct { // It takes a relative offset pos that can be resolved into // an absolute offset using state.offsetAt. // -// It takes a where that specify how the JSON pointer is derived. +// It takes a where that specifies how the JSON pointer is derived. // If the underlying error is a [pointerSuffixError], // then the suffix is appended to the derived pointer. func wrapSyntacticError(state interface { + options() *jsonopts.Struct offsetAt(pos int) int64 AppendStackPointer(b []byte, where int) []byte }, err error, pos, where int) error { @@ -83,6 +99,21 @@ func wrapSyntacticError(state interface { } err = jsonwire.NewInvalidCharacterError(d.buf[pos:], where) } + if state.options().Flags.Get(jsonflags.ReportErrorsWithLegacySemantics) && err != io.ErrUnexpectedEOF { + // The v1 error offset more consistently reported + // the number of bytes read that lead to the error. + // This implies that the offset is after the invalid text. + if werr, ok := err.(*jsonwire.InvalidTextError); ok && werr != nil { + offset += int64(len(werr.What)) + } else { + // This implies a structural error (e.g., parsing a JSON number + // when the grammar is expecting a JSON string for the object name). + // In such a case, simply increment by one, since the first byte + // is usually sufficient to indicate that the incoming token + // cannot possibly be correct. + offset++ + } + } return &SyntacticError{ByteOffset: offset, JSONPointer: Pointer(ptr), Err: err} } diff --git a/vendor/github.com/go-json-experiment/json/jsontext/export.go b/vendor/github.com/go-json-experiment/json/jsontext/export.go index 866954b..3ebbce0 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/export.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/export.go @@ -12,6 +12,20 @@ import ( "github.com/go-json-experiment/json/internal" ) +// TODO(https://go.dev/issue/73435): Remove the Internal symbol. +// +// The Go language lacks a 3rd category of visibility where +// certain symbols can only be referenced from within the same module. +// One solution to this is to put the entirety of a package with +// both public and module-only symbols exposed as an internal package. +// A separate, public package can re-export all of the public symbols +// via type aliases and thus ensuring module-only symbols cannot be +// referenced by the end-user. While this works, it unfortunately +// leads to a poor user experience since the Go pkgsite is unable to +// forward the documentation for symbols like methods and fields. +// We need to improve the pkgsite experience before we can delete +// the Internal symbol. + // Internal is for internal use only. // This is exempt from the Go compatibility agreement. var Internal exporter diff --git a/vendor/github.com/go-json-experiment/json/jsontext/options.go b/vendor/github.com/go-json-experiment/json/jsontext/options.go index 5681902..19edb21 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/options.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/options.go @@ -17,7 +17,7 @@ import ( // Options configures [NewEncoder], [Encoder.Reset], [NewDecoder], // and [Decoder.Reset] with specific features. // Each function takes in a variadic list of options, where properties -// set in latter options override the value of previously set properties. +// set in later options override the value of previously set properties. // // There is a single Options type, which is used with both encoding and decoding. // Some options affect both operations, while others only affect one operation: @@ -147,7 +147,7 @@ func CanonicalizeRawInts(v bool) Options { // It is safe to canonicalize a serialized single precision number and // parse it back as a single precision number and expect the same value. // If a number exceeds ±1.7976931348623157e+308, which is the maximum -// finite number, then it saturated at that value and formatted as such. +// finite number, then it is saturated at that value and formatted as such. // // This only affects encoding and is ignored when decoding. func CanonicalizeRawFloats(v bool) Options { @@ -205,7 +205,7 @@ func SpaceAfterComma(v bool) Options { // If [SpaceAfterComma] is not specified, then the default is false. // If [WithIndent] is not specified, then the default is "\t". // -// If set to false, then the output is a single-line, +// If set to false, then the output is a single line, // where the only whitespace emitted is determined by the current // values of [SpaceAfterColon] and [SpaceAfterComma]. // @@ -222,9 +222,9 @@ func Multiline(v bool) Options { // where each element in a JSON object or array begins on a new, indented line // beginning with the indent prefix (see [WithIndentPrefix]) // followed by one or more copies of indent according to the nesting depth. -// The indent must only be composed of space or tab characters. +// The indent must be composed of only space and tab characters. // -// If the intent to emit indented output without a preference for +// If the intent is to emit indented output without a preference for // the particular indent string, then use [Multiline] instead. // // This only affects encoding and is ignored when decoding. @@ -249,7 +249,7 @@ func WithIndent(indent string) Options { // Otherwise, allocate for this unique value. if s := strings.Trim(indent, " \t"); len(s) > 0 { - panic("json: invalid character " + jsonwire.QuoteRune(s) + " in indent") + panic("json: invalid character " + jsonwire.QuoteRune([]byte(s)) + " in indent") } return jsonopts.Indent(indent) } @@ -258,13 +258,13 @@ func WithIndent(indent string) Options { // where each element in a JSON object or array begins on a new, indented line // beginning with the indent prefix followed by one or more copies of indent // (see [WithIndent]) according to the nesting depth. -// The prefix must only be composed of space or tab characters. +// The prefix must be composed of only space and tab characters. // // This only affects encoding and is ignored when decoding. // Use of this option implies [Multiline] being set to true. func WithIndentPrefix(prefix string) Options { if s := strings.Trim(prefix, " \t"); len(s) > 0 { - panic("json: invalid character " + jsonwire.QuoteRune(s) + " in indent prefix") + panic("json: invalid character " + jsonwire.QuoteRune([]byte(s)) + " in indent prefix") } return jsonopts.IndentPrefix(prefix) } diff --git a/vendor/github.com/go-json-experiment/json/jsontext/pools.go b/vendor/github.com/go-json-experiment/json/jsontext/pools.go index cf59d99..75a91ae 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/pools.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/pools.go @@ -54,6 +54,10 @@ func getBufferedEncoder(opts ...Options) *Encoder { return e } func putBufferedEncoder(e *Encoder) { + if cap(e.s.availBuffer) > 64<<10 { + e.s.availBuffer = nil // avoid pinning arbitrarily large amounts of memory + } + // Recycle large buffers only if sufficiently utilized. // If a buffer is under-utilized enough times sequentially, // then it is discarded, ensuring that a single large buffer @@ -95,9 +99,14 @@ func getStreamingEncoder(w io.Writer, opts ...Options) *Encoder { } } func putStreamingEncoder(e *Encoder) { + if cap(e.s.availBuffer) > 64<<10 { + e.s.availBuffer = nil // avoid pinning arbitrarily large amounts of memory + } if _, ok := e.s.wr.(*bytes.Buffer); ok { + e.s.wr, e.s.Buf = nil, nil // avoid pinning the provided bytes.Buffer bytesBufferEncoderPool.Put(e) } else { + e.s.wr = nil // avoid pinning the provided io.Writer if cap(e.s.Buf) > 64<<10 { e.s.Buf = nil // avoid pinning arbitrarily large amounts of memory } @@ -126,6 +135,7 @@ func getBufferedDecoder(b []byte, opts ...Options) *Decoder { return d } func putBufferedDecoder(d *Decoder) { + d.s.buf = nil // avoid pinning the provided buffer bufferedDecoderPool.Put(d) } @@ -142,8 +152,10 @@ func getStreamingDecoder(r io.Reader, opts ...Options) *Decoder { } func putStreamingDecoder(d *Decoder) { if _, ok := d.s.rd.(*bytes.Buffer); ok { + d.s.rd, d.s.buf = nil, nil // avoid pinning the provided bytes.Buffer bytesBufferDecoderPool.Put(d) } else { + d.s.rd = nil // avoid pinning the provided io.Reader if cap(d.s.buf) > 64<<10 { d.s.buf = nil // avoid pinning arbitrarily large amounts of memory } diff --git a/vendor/github.com/go-json-experiment/json/jsontext/quote.go b/vendor/github.com/go-json-experiment/json/jsontext/quote.go index 8d475b8..5920aa1 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/quote.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/quote.go @@ -18,7 +18,7 @@ import ( // and an error is returned at the end indicating the presence of invalid UTF-8. // The dst must not overlap with the src. func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error) { - dst, err := jsonwire.AppendQuote(dst, src, &jsonflags.Flags{}) + dst, err := jsonwire.AppendQuote(dst, []byte(src), &jsonflags.Flags{}) if err != nil { err = &SyntacticError{Err: err} } @@ -33,7 +33,7 @@ func AppendQuote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error) // Any trailing bytes after the JSON string literal results in an error. // The dst must not overlap with the src. func AppendUnquote[Bytes ~[]byte | ~string](dst []byte, src Bytes) ([]byte, error) { - dst, err := jsonwire.AppendUnquote(dst, src) + dst, err := jsonwire.AppendUnquote(dst, []byte(src)) if err != nil { err = &SyntacticError{Err: err} } diff --git a/vendor/github.com/go-json-experiment/json/jsontext/state.go b/vendor/github.com/go-json-experiment/json/jsontext/state.go index 2da28c1..ab3a07b 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/state.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/state.go @@ -24,8 +24,8 @@ import ( // The name of a duplicate JSON object member can be extracted as: // // err := ... -// var serr jsontext.SyntacticError -// if errors.As(err, &serr) && serr.Err == jsontext.ErrDuplicateName { +// serr, ok := errors.AsType[*jsontext.SyntacticError](err) +// if ok && serr.Err == jsontext.ErrDuplicateName { // ptr := serr.JSONPointer // JSON pointer to duplicate name // name := ptr.LastToken() // duplicate name itself // ... @@ -86,12 +86,12 @@ func (s *state) reset() { // either a JSON object name or an index to a JSON array element // encoded as a base-10 integer value. // It is impossible to distinguish between an array index and an object name -// (that happens to be an base-10 encoded integer) without also knowing +// (that happens to be a base-10 encoded integer) without also knowing // the structure of the top-level JSON value that the pointer refers to. // // There is exactly one representation of a pointer to a particular value, // so comparability of Pointer values is equivalent to checking whether -// they both point to the exact same value. +// they both point to the same value. type Pointer string // IsValid reports whether p is a valid JSON Pointer according to RFC 6901. @@ -117,13 +117,13 @@ func (p Pointer) Contains(pc Pointer) bool { } // Parent strips off the last token and returns the remaining pointer. -// The parent of an empty p is an empty string. +// The parent of an empty Pointer is the empty string. func (p Pointer) Parent() Pointer { return p[:max(strings.LastIndexByte(string(p), '/'), 0)] } // LastToken returns the last token in the pointer. -// The last token of an empty p is an empty string. +// The last token of an empty Pointer is the empty string. func (p Pointer) LastToken() string { last := p[max(strings.LastIndexByte(string(p), '/'), 0):] return unescapePointerToken(strings.TrimPrefix(string(last), "/")) @@ -131,14 +131,14 @@ func (p Pointer) LastToken() string { // AppendToken appends a token to the end of p and returns the full pointer. func (p Pointer) AppendToken(tok string) Pointer { - return Pointer(appendEscapePointerName([]byte(p+"/"), tok)) + return Pointer(appendEscapePointerName([]byte(p+"/"), []byte(tok))) } // TODO: Add Pointer.AppendTokens, // but should this take in a ...string or an iter.Seq[string]? // Tokens returns an iterator over the reference tokens in the JSON pointer, -// starting from the first token until the last token (unless stopped early). +// from first to last. func (p Pointer) Tokens() iter.Seq[string] { return func(yield func(string) bool) { for len(p) > 0 { @@ -202,7 +202,7 @@ func (s state) appendStackPointer(b []byte, where int) []byte { return b } -func appendEscapePointerName[Bytes ~[]byte | ~string](b []byte, name Bytes) []byte { +func appendEscapePointerName(b, name []byte) []byte { for _, r := range string(name) { // Per RFC 6901, section 3, escape '~' and '/' characters. switch r { @@ -439,7 +439,7 @@ const ( stateTypeObject stateEntry = 0x8000_0000_0000_0000 stateTypeArray stateEntry = 0x0000_0000_0000_0000 - // The name check mask (2 bit) records whether to update + // The name check mask (2 bits) records whether to update // the namespaces for the current JSON object and // whether the namespace is valid. stateNamespaceMask stateEntry = 0x6000_0000_0000_0000 @@ -475,7 +475,7 @@ func (e stateEntry) NeedObjectName() bool { return e&(stateTypeMask|stateCountLSBMask) == stateTypeObject|stateCountEven } -// needImplicitColon reports whether an colon should occur next, +// needImplicitColon reports whether a colon should occur next, // which always occurs after JSON object names. func (e stateEntry) needImplicitColon() bool { return e.needObjectValue() @@ -487,7 +487,7 @@ func (e stateEntry) needObjectValue() bool { return e&(stateTypeMask|stateCountLSBMask) == stateTypeObject|stateCountOdd } -// needImplicitComma reports whether an comma should occur next, +// needImplicitComma reports whether a comma should occur next, // which always occurs after a value in a JSON object or array // before the next value (or name). func (e stateEntry) needImplicitComma(next Kind) bool { @@ -502,7 +502,7 @@ func (e *stateEntry) Increment() { } // decrement decrements the number of elements for the current object or array. -// It is the callers responsibility to ensure that e.length > 0. +// It is the caller's responsibility to ensure that e.length > 0. func (e *stateEntry) decrement() { (*e)-- } @@ -575,7 +575,7 @@ func (ns *objectNameStack) getUnquoted(i int) []byte { if i == 0 { return ns.unquotedNames[:ns.offsets[0]] } else { - return ns.unquotedNames[ns.offsets[i-1]:ns.offsets[i-0]] + return ns.unquotedNames[ns.offsets[i-1]:ns.offsets[i]] } } @@ -706,7 +706,7 @@ func (nss *objectNamespaceStack) pop() { } // objectNamespace is the namespace for a JSON object. -// In contrast to objectNameStack, this needs to remember a all names +// In contrast to objectNameStack, this needs to remember all names // per JSON object. // // The zero value is an empty namespace ready for use. @@ -747,7 +747,7 @@ func (ns *objectNamespace) getUnquoted(i int) []byte { if i == 0 { return ns.allUnquotedNames[:ns.endOffsets[0]] } else { - return ns.allUnquotedNames[ns.endOffsets[i-1]:ns.endOffsets[i-0]] + return ns.allUnquotedNames[ns.endOffsets[i-1]:ns.endOffsets[i]] } } diff --git a/vendor/github.com/go-json-experiment/json/jsontext/token.go b/vendor/github.com/go-json-experiment/json/jsontext/token.go index 23911df..20c1628 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/token.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/token.go @@ -39,6 +39,20 @@ var errInvalidToken = errors.New("invalid jsontext.Token") // A Token cannot represent entire array or object values, while a [Value] can. // There is no Token to represent commas and colons since // these structural tokens can be inferred from the surrounding context. +// +// A Token stores data in one of two forms: +// +// - As raw JSON text: backed by the internal buffer of the [Decoder] +// and only ever produced by [Decoder.ReadToken]. +// Such a token is only valid until the next call to any method on that +// [Decoder] (e.g., [Decoder.PeekKind], [Decoder.ReadToken], +// [Decoder.ReadValue], or [Decoder.SkipValue]). +// Call [Token.Clone] to copy the raw text into an independent allocation +// that persists beyond subsequent [Decoder] calls. +// +// - As a typed Go value: a self-contained representation produced by +// the constructor functions (e.g., [String], [Int], [Uint], [Float]). +// Such tokens are valid indefinitely and do not need to be cloned. type Token struct { nonComparable @@ -48,21 +62,22 @@ type Token struct { // The Encoder accepts Tokens in either the "raw" or "exact" form. // // The following chart shows the possible values for each Token type: - // ╔═════════════════╦════════════╤════════════╤════════════╗ - // ║ Token type ║ raw field │ str field │ num field ║ - // ╠═════════════════╬════════════╪════════════╪════════════╣ - // ║ null (raw) ║ "null" │ "" │ 0 ║ - // ║ false (raw) ║ "false" │ "" │ 0 ║ - // ║ true (raw) ║ "true" │ "" │ 0 ║ - // ║ string (raw) ║ non-empty │ "" │ offset ║ - // ║ string (string) ║ nil │ non-empty │ 0 ║ - // ║ number (raw) ║ non-empty │ "" │ offset ║ - // ║ number (float) ║ nil │ "f" │ non-zero ║ - // ║ number (int64) ║ nil │ "i" │ non-zero ║ - // ║ number (uint64) ║ nil │ "u" │ non-zero ║ - // ║ object (delim) ║ "{" or "}" │ "" │ 0 ║ - // ║ array (delim) ║ "[" or "]" │ "" │ 0 ║ - // ╚═════════════════╩════════════╧════════════╧════════════╝ + // ╔══════════════════╦════════════╤════════════╤════════════╗ + // ║ Token type ║ raw field │ str field │ num field ║ + // ╠══════════════════╬════════════╪════════════╪════════════╣ + // ║ null (raw) ║ "null" │ "" │ 0 ║ + // ║ false (raw) ║ "false" │ "" │ 0 ║ + // ║ true (raw) ║ "true" │ "" │ 0 ║ + // ║ string (raw) ║ non-empty │ "" │ offset ║ + // ║ string (string) ║ nil │ non-empty │ 0 ║ + // ║ number (raw) ║ non-empty │ "" │ offset ║ + // ║ number (float32) ║ nil │ "F" │ non-zero ║ + // ║ number (float64) ║ nil │ "f" │ non-zero ║ + // ║ number (int64) ║ nil │ "i" │ non-zero ║ + // ║ number (uint64) ║ nil │ "u" │ non-zero ║ + // ║ object (delim) ║ "{" or "}" │ "" │ 0 ║ + // ║ array (delim) ║ "[" or "]" │ "" │ 0 ║ + // ╚══════════════════╩════════════╧════════════╧════════════╝ // // Notes: // - For tokens stored in "raw" form, the num field contains the @@ -80,11 +95,12 @@ type Token struct { raw *decodeBuffer // str is the unescaped JSON string if num is zero. - // Otherwise, it is "f", "i", or "u" if num should be interpreted - // as a float64, int64, or uint64, respectively. + // Otherwise, it is "F", "f", "i", or "u" if num should be interpreted + // as a float32, float64, int64, or uint64, respectively. str string - // num is a float64, int64, or uint64 stored as a uint64 value. + // num is a float32, float64, int64, or uint64 stored as a uint64 value. + // For floating-point values, it stores the raw IEEE-754 bit-pattern. // It is non-zero for any JSON number in the "exact" form. num uint64 } @@ -131,7 +147,29 @@ func String(s string) Token { return Token{str: s} } -// Float constructs a Token representing a JSON number. +// Float32 constructs a Token representing a JSON number as +// a 32-bit floating-point number formatted according to +// ECMA-262, 10th edition, section 7.1.12.1, +// with the exception that -0 is still formatted as -0. +// The values NaN, +Inf, and -Inf will be represented +// as a JSON string with the values "NaN", "Infinity", and "-Infinity". +// +// Note that most JSON libraries and standards assume that JSON numbers +// are 64-bit floating-point numbers. Use of 32-bit precision should +// only be used if the corresponding decoder knows that +// this JSON number token is expected to only have 32-bit precision. +// For all other situations, prefer using the [Float] constructor instead. +func Float32(n float32) Token { + if n != 0 && !math.IsNaN(float64(n)) && !math.IsInf(float64(n), 0) { + return Token{str: "F", num: uint64(math.Float32bits(n))} + } + return Float(float64(n)) // handles ±0, NaN, and ±Inf +} + +// Float constructs a Token representing a JSON number as +// a 64-bit floating-point number formatted according to +// ECMA-262, 10th edition, section 7.1.12.1 and RFC 8785, section 3.2.2.3. +// with the exception that -0 is still formatted as -0. // The values NaN, +Inf, and -Inf will be represented // as a JSON string with the values "NaN", "Infinity", and "-Infinity". func Float(n float64) Token { @@ -164,8 +202,10 @@ func Uint(n uint64) Token { return Token{str: "u", num: uint64(n)} } -// Clone makes a copy of the Token such that its value remains valid -// even after a subsequent [Decoder.Read] call. +// Clone returns a copy of the token with a value that is not backed by the +// [Decoder] buffer and therefore remains valid past subsequent [Decoder] calls. +// It has no effect on tokens produced by constructor functions, +// since those are already self-contained. func (t Token) Clone() Token { // TODO: Allow caller to avoid any allocations? if raw := t.raw; raw != nil { @@ -189,6 +229,7 @@ func (t Token) Clone() Token { } } + // This only ever needs to clone strings and numbers. if uint64(raw.previousOffsetStart()) != t.num { panic(invalidTokenPanic) } @@ -226,7 +267,7 @@ func (t Token) appendString(dst []byte, flags *jsonflags.Flags) ([]byte, error) } } else if len(t.str) != 0 && t.num == 0 { // Handle exact string value. - return jsonwire.AppendQuote(dst, t.str, flags) + return jsonwire.AppendQuote(dst, []byte(t.str), flags) } panic("invalid JSON token kind: " + t.Kind().String()) @@ -265,8 +306,10 @@ func (t Token) string() (string, []byte) { // Handle tokens that are not JSON strings for fmt.Stringer. if t.num > 0 { switch t.str[0] { + case 'F': + return string(jsonwire.AppendFloat(nil, float64(math.Float32frombits(uint32(t.num))), 32)), nil case 'f': - return string(jsonwire.AppendFloat(nil, math.Float64frombits(t.num), 64)), nil + return string(jsonwire.AppendFloat(nil, float64(math.Float64frombits(uint64(t.num))), 64)), nil case 'i': return strconv.FormatInt(int64(t.num), 10), nil case 'u': @@ -289,8 +332,10 @@ func (t Token) appendNumber(dst []byte, flags *jsonflags.Flags) ([]byte, error) } else if t.num != 0 { // Handle exact number value. switch t.str[0] { + case 'F': + return jsonwire.AppendFloat(dst, float64(math.Float32frombits(uint32(t.num))), 32), nil case 'f': - return jsonwire.AppendFloat(dst, math.Float64frombits(t.num), 64), nil + return jsonwire.AppendFloat(dst, float64(math.Float64frombits(uint64(t.num))), 64), nil case 'i': return strconv.AppendInt(dst, int64(t.num), 10), nil case 'u': @@ -301,30 +346,77 @@ func (t Token) appendNumber(dst []byte, flags *jsonflags.Flags) ([]byte, error) panic("invalid JSON token kind: " + t.Kind().String()) } -// Float returns the floating-point value for a JSON number. +// Float32 returns the floating-point value for a JSON number +// parsed according to 32 bits of precision. +// +// If the JSON number is outside the representable range of a float32, +// it returns +Inf or -Inf along with an error +// that matches [strconv.ErrRange] according to [errors.Is]. +// // It returns a NaN, +Inf, or -Inf value for any JSON string // with the values "NaN", "Infinity", or "-Infinity". -// It panics for all other cases. -func (t Token) Float() float64 { +// +// It panics if the token kind is not a JSON number +// or a JSON string with the aforementioned values. +// +// Note that most JSON libraries and standards assume that JSON numbers +// are 64-bit floating-point numbers. +// This method should only be used if the caller knows +// from other context that this token is a JSON number +// formatted only to 32 bits of precision (such as being encoded +// using the [Float32] constructor). For all other situations, +// prefer using the [Token.Float] accessor instead. +func (t Token) Float32() (float32, error) { + f, err := t.float(32) + return float32(f), err +} + +// Float returns the floating-point value for a JSON number +// parsed according to 64 bits of precision. +// +// If the JSON number is outside the representable range of a float64, +// it returns +Inf or -Inf along with an error +// that matches [strconv.ErrRange] according to [errors.Is]. +// +// It returns a NaN, +Inf, or -Inf value for any JSON string +// with the values "NaN", "Infinity", or "-Infinity". +// +// It panics if the token kind is not a JSON number +// or a JSON string with the aforementioned values. +func (t Token) Float() (float64, error) { + f, err := t.float(64) + return float64(f), err +} + +func (t Token) float(bits int) (float64, error) { if raw := t.raw; raw != nil { - // Handle raw number value. + // Handle raw JSON number value. if uint64(raw.previousOffsetStart()) != t.num { panic(invalidTokenPanic) } buf := raw.previousBuffer() if Kind(buf[0]).normalize() == '0' { - fv, _ := jsonwire.ParseFloat(buf, 64) - return fv + fv, err := strconv.ParseFloat(string(buf), bits) + if err != nil { + err = &numError{accessor: "Float", value: t.String(), err: errors.Unwrap(err)} // only ever ErrRange + } + return fv, err } } else if t.num != 0 { - // Handle exact number value. + // Handle typed Go number value. switch t.str[0] { + case 'F': + return float64(math.Float32frombits(uint32(t.num))), nil case 'f': - return math.Float64frombits(t.num) + f64 := float64(math.Float64frombits(uint64(t.num))) + if bits == 32 && !math.IsInf(f64, 0) && math.IsInf(float64(float32(f64)), 0) { + return f64, &numError{accessor: "Float", value: t.String(), err: strconv.ErrRange} + } + return f64, nil case 'i': - return float64(int64(t.num)) + return float64(int64(t.num)), nil // NOTE: This may lead to loss of precision. case 'u': - return float64(uint64(t.num)) + return float64(uint64(t.num)), nil // NOTE: This may lead to loss of precision. } } @@ -332,128 +424,181 @@ func (t Token) Float() float64 { if t.Kind() == '"' { switch t.String() { case "NaN": - return math.NaN() + return math.NaN(), nil case "Infinity": - return math.Inf(+1) + return math.Inf(+1), nil case "-Infinity": - return math.Inf(-1) + return math.Inf(-1), nil } + // TODO: Should this be an error instead of a panic? + // We can safely switch from a panic to an error in the future. } panic("invalid JSON token kind: " + t.Kind().String()) } // Int returns the signed integer value for a JSON number. +// +// It reports an error that matches [strconv.ErrSyntax] according to [errors.Is] +// if the JSON number does not match the restricted grammar of just a signed integer. +// It reports an error that matches [strconv.ErrRange] according to [errors.Is] +// if the JSON number is a signed integer, but outside the range of an int64. +// Even if an error is reported, a reasonable value is still returned. // The fractional component of any number is ignored (truncation toward zero). // Any number beyond the representation of an int64 will be saturated // to the closest representable value. +// // It panics if the token kind is not a JSON number. -func (t Token) Int() int64 { +func (t Token) Int() (int64, error) { if raw := t.raw; raw != nil { - // Handle raw integer value. + // Handle raw JSON number value. if uint64(raw.previousOffsetStart()) != t.num { panic(invalidTokenPanic) } - neg := false buf := raw.previousBuffer() if len(buf) > 0 && buf[0] == '-' { - neg, buf = true, buf[1:] - } - if numAbs, ok := jsonwire.ParseUint(buf); ok { - if neg { - if numAbs > -minInt64 { - return minInt64 - } - return -1 * int64(numAbs) - } else { - if numAbs > +maxInt64 { - return maxInt64 - } - return +1 * int64(numAbs) + // Prospectively parse a negative integer. + switch abs, ok := jsonwire.ParseUint(buf[len("-"):]); { + case abs > -minInt64: + return minInt64, &numError{accessor: "Int", value: t.String(), err: strconv.ErrRange} + case ok: + return -1 * int64(abs), nil } + } else { + // Prospectively parse a non-negative integer. + switch abs, ok := jsonwire.ParseUint(buf); { + case abs > +maxInt64: + return maxInt64, &numError{accessor: "Int", value: t.String(), err: strconv.ErrRange} + case ok: + return +1 * int64(abs), nil + } + } + // This is not a signed integer, which implies ErrSyntax. + if Kind(buf[0]).normalize() == '0' { + f64, _ := strconv.ParseFloat(string(buf), 64) + return f64toi64(f64), &numError{accessor: "Int", value: t.String(), err: strconv.ErrSyntax} } } else if t.num != 0 { - // Handle exact integer value. + // Handle typed Go number value. switch t.str[0] { case 'i': - return int64(t.num) + return int64(t.num), nil case 'u': if t.num > maxInt64 { - return maxInt64 + return maxInt64, &numError{accessor: "Int", value: t.String(), err: strconv.ErrRange} + } + return int64(t.num), nil + case 'f', 'F': + f64 := float64(math.Float64frombits(uint64(t.num))) + if t.str[0] == 'F' { + f64 = float64(math.Float32frombits(uint32(t.num))) + } + switch i64 := f64toi64(f64); { + case math.IsNaN(f64), math.Trunc(f64) != f64: + return i64, &numError{accessor: "Int", value: t.String(), err: strconv.ErrSyntax} + case (i64 == minInt64 && f64 < minInt64) || (i64 == maxInt64 && f64 > maxInt64): + return i64, &numError{accessor: "Int", value: t.String(), err: strconv.ErrRange} + default: + return i64, nil } - return int64(t.num) - } - } - - // Handle JSON number that is a floating-point value. - if t.Kind() == '0' { - switch fv := t.Float(); { - case fv >= maxInt64: - return maxInt64 - case fv <= minInt64: - return minInt64 - default: - return int64(fv) // truncation toward zero } } panic("invalid JSON token kind: " + t.Kind().String()) } +func f64toi64(f64 float64) int64 { + switch { + case math.IsNaN(f64): + return 0 + case f64 >= maxInt64+1: + return maxInt64 + case f64 < minInt64: + return minInt64 + default: + return int64(f64) // NOTE: This may lead to loss of precision. + } +} + // Uint returns the unsigned integer value for a JSON number. +// +// It reports an error that matches [strconv.ErrSyntax] if the JSON number +// does not match the restricted grammar of just an unsigned integer. +// It reports an error that matches [strconv.ErrRange] if the JSON number +// is an unsigned integer, but outside the representable range of a uint64. +// Even if an error is reported, a reasonable value is still returned. // The fractional component of any number is ignored (truncation toward zero). -// Any number beyond the representation of an uint64 will be saturated +// Any number beyond the representation of a uint64 will be saturated // to the closest representable value. +// // It panics if the token kind is not a JSON number. -func (t Token) Uint() uint64 { +func (t Token) Uint() (uint64, error) { // NOTE: This accessor returns 0 for any negative JSON number, // which might be surprising, but is at least consistent with the behavior // of saturating out-of-bounds numbers to the closest representable number. + // We report ErrSyntax instead of ErrRange since the grammar for + // an unsigned integer does not permit a negative sign. if raw := t.raw; raw != nil { - // Handle raw integer value. + // Handle raw JSON number value. if uint64(raw.previousOffsetStart()) != t.num { panic(invalidTokenPanic) } - neg := false buf := raw.previousBuffer() - if len(buf) > 0 && buf[0] == '-' { - neg, buf = true, buf[1:] + // Prospectively parse an unsigned integer. + switch abs, ok := jsonwire.ParseUint(buf); { + case ok: + return abs, nil + case abs == maxUint64: // implies overflows + return maxUint64, &numError{accessor: "Uint", value: t.String(), err: strconv.ErrRange} } - if num, ok := jsonwire.ParseUint(buf); ok { - if neg { - return minUint64 - } - return num + // This is not an unsigned integer, which implies ErrSyntax. + if Kind(buf[0]).normalize() == '0' { + f64, _ := strconv.ParseFloat(string(buf), 64) + return f64tou64(f64), &numError{accessor: "Uint", value: t.String(), err: strconv.ErrSyntax} } } else if t.num != 0 { - // Handle exact integer value. + // Handle typed Go number value. switch t.str[0] { case 'u': - return t.num + return t.num, nil case 'i': if int64(t.num) < minUint64 { - return minUint64 + return minUint64, &numError{accessor: "Uint", value: t.String(), err: strconv.ErrSyntax} + } + return uint64(int64(t.num)), nil + case 'f', 'F': + f64 := float64(math.Float64frombits(uint64(t.num))) + if t.str[0] == 'F' { + f64 = float64(math.Float32frombits(uint32(t.num))) + } + switch u64 := f64tou64(f64); { + case math.IsNaN(f64), math.Trunc(f64) != f64, math.Signbit(f64): + return u64, &numError{accessor: "Uint", value: t.String(), err: strconv.ErrSyntax} + case (u64 == minUint64 && f64 < minUint64) || (u64 == maxUint64 && f64 > maxUint64): + return u64, &numError{accessor: "Uint", value: t.String(), err: strconv.ErrRange} + default: + return u64, nil } - return uint64(int64(t.num)) - } - } - - // Handle JSON number that is a floating-point value. - if t.Kind() == '0' { - switch fv := t.Float(); { - case fv >= maxUint64: - return maxUint64 - case fv <= minUint64: - return minUint64 - default: - return uint64(fv) // truncation toward zero } } panic("invalid JSON token kind: " + t.Kind().String()) } +func f64tou64(f64 float64) uint64 { + switch { + case math.IsNaN(f64): + return 0 + case f64 >= maxUint64+1: + return maxUint64 + case f64 < minUint64: + return minUint64 + default: + return uint64(f64) // NOTE: This may lead to loss of precision. + } +} + // Kind returns the token kind. func (t Token) Kind() Kind { switch { @@ -472,29 +617,33 @@ func (t Token) Kind() Kind { } } -// Kind represents each possible JSON token kind with a single byte, -// which is conveniently the first byte of that kind's grammar -// with the restriction that numbers always be represented with '0': +// A Kind represents the kind of a JSON token. // -// - 'n': null -// - 'f': false -// - 't': true -// - '"': string -// - '0': number -// - '{': object begin -// - '}': object end -// - '[': array begin -// - ']': array end -// -// An invalid kind is usually represented using 0, -// but may be non-zero due to invalid JSON data. +// A Kind is a single byte, which is conveniently the first byte of that +// kind's symbol in the grammar (except for numbers, which are always represented +// with '0'). type Kind byte +const ( + KindInvalid Kind = 0 // invalid kind + KindNull Kind = 'n' // null + KindFalse Kind = 'f' // false + KindTrue Kind = 't' // true + KindString Kind = '"' // string + KindNumber Kind = '0' // number + KindBeginObject Kind = '{' // begin object + KindEndObject Kind = '}' // end object + KindBeginArray Kind = '[' // begin array + KindEndArray Kind = ']' // end array +) + const invalidKind Kind = 0 -// String prints the kind in a humanly readable fashion. +// String returns a string representation of k. func (k Kind) String() string { switch k { + case 0: + return "invalid" case 'n': return "null" case 'f': @@ -514,14 +663,35 @@ func (k Kind) String() string { case ']': return "]" default: - return "" + return "" } } -// normalize coalesces all possible starting characters of a number as just '0'. +var normKind = [256]Kind{ + 'n': 'n', + 'f': 'f', + 't': 't', + '"': '"', + '{': '{', + '}': '}', + '[': '[', + ']': ']', + '-': '0', + '0': '0', + '1': '0', + '2': '0', + '3': '0', + '4': '0', + '5': '0', + '6': '0', + '7': '0', + '8': '0', + '9': '0', +} + +// normalize coalesces all possible starting characters of a number as just '0', +// and converts all invalid kinds to 0. func (k Kind) normalize() Kind { - if k == '-' || ('0' <= k && k <= '9') { - return '0' - } - return k + // A lookup table keeps the inlining cost as low as possible. + return normKind[k] } diff --git a/vendor/github.com/go-json-experiment/json/jsontext/value.go b/vendor/github.com/go-json-experiment/json/jsontext/value.go index baaadda..afcbd0d 100644 --- a/vendor/github.com/go-json-experiment/json/jsontext/value.go +++ b/vendor/github.com/go-json-experiment/json/jsontext/value.go @@ -17,7 +17,24 @@ import ( "github.com/go-json-experiment/json/internal/jsonwire" ) -// NOTE: Value is analogous to v1 json.RawMessage. +// AppendFloat appends src to dst as a JSON number per RFC 8259, section 6. +// +// Except for -0, which is formatted as -0 instead of 0, +// the output is identical to ECMA-262, 10th edition, section 7.1.12.1 +// and (for 64-bit precision) identical to RFC 8785, section 3.2.2.3. +// The values NaN, +Inf, and -Inf will be represented as a JSON string +// with the values "NaN", "Infinity", and "-Infinity". +// +// Note that most JSON libraries and standards assume that JSON numbers +// are 64-bit floating-point numbers. As such, prefer using 64 bits +// of precision unless the recipient can know from other context +// that the encoded number uses 32 bits of precision. +func AppendFloat(dst []byte, src float64, bits int) []byte { + if bits != 32 && bits != 64 { + panic("illegal AppendFloat bit size") + } + return jsonwire.AppendFloat(dst, src, bits) +} // AppendFormat formats the JSON value in src and appends it to dst // according to the specified options. @@ -25,16 +42,18 @@ import ( // // The dst and src may overlap. // If an error is reported, then the entirety of src is appended to dst. -func AppendFormat(dst, src []byte, opts ...Options) ([]byte, error) { +func AppendFormat[Bytes ~[]byte | ~string](dst []byte, src Bytes, opts ...Options) ([]byte, error) { e := getBufferedEncoder(opts...) defer putBufferedEncoder(e) e.s.Flags.Set(jsonflags.OmitTopLevelNewline | 1) - if err := e.s.WriteValue(src); err != nil { + if err := e.s.WriteValue(Value(src)); err != nil { return append(dst, src...), err } return append(dst, e.s.Buf...), nil } +// NOTE: Value is analogous to v1 json.RawMessage. + // Value represents a single raw JSON value, which may be one of the following: // - a JSON literal (i.e., null, true, or false) // - a JSON string (e.g., "hello, world!") @@ -113,7 +132,7 @@ func (v *Value) Format(opts ...Options) error { return v.format(opts, nil) } -// format accepts two []Options to avoid the allocation appending them together. +// format accepts two []Options to avoid the allocation of appending them together. // It is equivalent to v.Format(append(opts1, opts2...)...). func (v *Value) format(opts1, opts2 []Options) error { e := getBufferedEncoder(opts1...) @@ -133,7 +152,7 @@ func (v *Value) format(opts1, opts2 []Options) error { // // It does not reformat JSON strings or numbers to use any other representation. // To maximize the set of JSON values that can be formatted, -// this permits values with duplicate names and invalid UTF-8. +// it permits values with duplicate names and invalid UTF-8. // // Compact is equivalent to calling [Value.Format] with the following options: // - [AllowDuplicateNames](true) @@ -151,11 +170,11 @@ func (v *Value) Compact(opts ...Options) error { } // Indent reformats the whitespace in the raw JSON value so that each element -// in a JSON object or array begins on a indented line according to the nesting. +// in a JSON object or array begins on an indented line according to the nesting. // // It does not reformat JSON strings or numbers to use any other representation. // To maximize the set of JSON values that can be formatted, -// this permits values with duplicate names and invalid UTF-8. +// it permits values with duplicate names and invalid UTF-8. // // Indent is equivalent to calling [Value.Format] with the following options: // - [AllowDuplicateNames](true) @@ -175,8 +194,10 @@ func (v *Value) Indent(opts ...Options) error { } // Canonicalize canonicalizes the raw JSON value according to the -// JSON Canonicalization Scheme (JCS) as defined by RFC 8785 -// where it produces a stable representation of a JSON value. +// JSON Canonicalization Scheme (JCS) as defined by RFC 8785. +// Canonicalization produces a JSON value with the same meaning as the original, +// but is stable in the sense that calling Canonicalize on a canonicalized +// value does nothing. // // JSON strings are formatted to use their minimal representation, // JSON numbers are formatted as double precision numbers according @@ -184,12 +205,6 @@ func (v *Value) Indent(opts ...Options) error { // JSON object members are sorted in ascending order by name. // All whitespace is removed. // -// The output stability is dependent on the stability of the application data -// (see RFC 8785, Appendix E). It cannot produce stable output from -// fundamentally unstable input. For example, if the JSON value -// contains ephemeral data (e.g., a frequently changing timestamp), -// then the value is still unstable regardless of whether this is called. -// // Canonicalize is equivalent to calling [Value.Format] with the following options: // - [CanonicalizeRawInts](true) // - [CanonicalizeRawFloats](true) @@ -214,7 +229,7 @@ func (v *Value) Canonicalize(opts ...Options) error { } // MarshalJSON returns v as the JSON encoding of v. -// It returns the stored value as the raw JSON output without any validation. +// It performs no validation. // If v is nil, then this returns a JSON null. func (v Value) MarshalJSON() ([]byte, error) { // NOTE: This matches the behavior of v1 json.RawMessage.MarshalJSON. @@ -236,7 +251,7 @@ func (v *Value) UnmarshalJSON(b []byte) error { } // Kind returns the starting token kind. -// For a valid value, this will never include '}' or ']'. +// For a valid value, this will never include [KindEndObject] or [KindEndArray]. func (v Value) Kind() Kind { if v := v[jsonwire.ConsumeWhitespace(v):]; len(v) > 0 { return Kind(v[0]).normalize() diff --git a/vendor/github.com/go-json-experiment/json/migrate.sh b/vendor/github.com/go-json-experiment/json/migrate.sh index 9c34f26..b4aacbd 100644 --- a/vendor/github.com/go-json-experiment/json/migrate.sh +++ b/vendor/github.com/go-json-experiment/json/migrate.sh @@ -4,6 +4,8 @@ GOROOT=${1:-../go} JSONROOT="." cp $JSONROOT/alias_gen.go $JSONROOT/alias_gen.go.bak +cp $JSONROOT/options_format_global.go $JSONROOT/options_format_global.go.bak +cp $JSONROOT/options_format_test.go $JSONROOT/options_format_test.go.bak rm -r $JSONROOT/*.go $JSONROOT/internal $JSONROOT/jsontext $JSONROOT/v1 mv $JSONROOT/alias_gen.go.bak $JSONROOT/alias_gen.go cp -r $GOROOT/src/encoding/json/v2/*.go $JSONROOT/ @@ -18,6 +20,8 @@ for X in $(git ls-files --cached --others --exclude-standard | grep ".*[.]go$"); if [ ! -e "$X" ]; then continue fi + sed -i 's/go:build goexperiment.jsonv2 && !goexperiment.jsonformat$/go:build (!goexperiment.jsonv2 || !go1.25) \&\& !goexperiment.jsonformat/' $X + sed -i 's/go:build goexperiment.jsonv2 && goexperiment.jsonformat$/go:build (!goexperiment.jsonv2 || !go1.25) \&\& goexperiment.jsonformat/' $X sed -i 's/go:build goexperiment.jsonv2$/go:build !goexperiment.jsonv2 || !go1.25/' $X sed -i 's|"encoding/json/v2"|"github.com/go-json-experiment/json"|' $X sed -i 's|"encoding/json/internal"|"github.com/go-json-experiment/json/internal"|' $X @@ -32,10 +36,7 @@ for X in $(git ls-files --cached --others --exclude-standard | grep ".*[.]go$"); done sed -i 's/v2[.]struct/json.struct/' $JSONROOT/errors_test.go sed -i 's|jsonv1 "github.com/go-json-experiment/json/v1"|jsonv1 "encoding/json"|' $JSONROOT/bench_test.go - -# TODO(go1.25): Remove test that relies on "synctest" that is not available yet. -sed -i '/Issue #73733/,+17d' $JSONROOT/v1/encode_test.go -goimports -w $JSONROOT/v1/encode_test.go +sed -i '/testenv/d' $JSONROOT/jsontext/token_test.go # Remove documentation that only makes sense within the stdlib. sed -i '/This package .* is experimental/,+4d' $JSONROOT/doc.go @@ -46,3 +47,14 @@ git checkout internal/zstd # we still need local copy of zstd for testing go run alias_gen.go "encoding/json" $JSONROOT/v1 go run alias_gen.go "encoding/json/v2" $JSONROOT go run alias_gen.go "encoding/json/jsontext" $JSONROOT/jsontext + +mv $JSONROOT/options_format_global.go.bak $JSONROOT/options_format_global.go +mv $JSONROOT/options_format_test.go.bak $JSONROOT/options_format_test.go +cp $GOROOT/src/encoding/json/internal/jsonopts/options_format.go $JSONROOT/options_format.go +sed -i '/go:build goexperiment.jsonv2/d' $JSONROOT/options_format.go +sed -i 's/package jsonopts/package json/' $JSONROOT/options_format.go +goimports -w $JSONROOT/options_format.go +sed -i -E '/^func (Marshal|MarshalWrite|MarshalEncode|Unmarshal|UnmarshalRead|UnmarshalDecode)\(/a opts = mayAppendSupportFormatTag(opts)' $JSONROOT/alias.go +sed -i -E '/^func (Marshal|MarshalWrite|MarshalEncode|Unmarshal|UnmarshalRead|UnmarshalDecode)\(/a opts = mayAppendSupportFormatTag(opts)' $JSONROOT/arshal.go +goimports -w $JSONROOT/alias.go +goimports -w $JSONROOT/arshal.go diff --git a/vendor/github.com/go-json-experiment/json/options.go b/vendor/github.com/go-json-experiment/json/options.go index 96758cb..d726c1e 100644 --- a/vendor/github.com/go-json-experiment/json/options.go +++ b/vendor/github.com/go-json-experiment/json/options.go @@ -23,11 +23,11 @@ import ( // [encoding/json/jsontext.Options]. Options from the other packages can // be used interchangeably with functionality in this package. // -// Options represent either a singular option or a set of options. -// It can be functionally thought of as a Go map of option properties +// An Options value represents either a single option or a set of options. +// It can be thought of as a Go map of option properties // (even though the underlying implementation avoids Go maps for performance). // -// The constructors (e.g., [Deterministic]) return a singular option value: +// The constructors (e.g., [Deterministic]) return a value for a single option: // // opt := Deterministic(true) // @@ -35,7 +35,7 @@ import ( // // opt := Options{"Deterministic": true} // -// [JoinOptions] composes multiple options values to together: +// [JoinOptions] composes multiple options values together: // // out := JoinOptions(opts...) // @@ -48,7 +48,7 @@ import ( // } // } // -// [GetOption] looks up the value of options parameter: +// [GetOption] looks up the value of an options parameter: // // v, ok := GetOption(opts, Deterministic) // @@ -65,7 +65,6 @@ import ( // - [FormatNilMapAsNull] affects marshaling only // - [OmitZeroStructFields] affects marshaling only // - [MatchCaseInsensitiveNames] affects marshaling and unmarshaling -// - [DiscardUnknownMembers] affects marshaling only // - [RejectUnknownMembers] affects unmarshaling only // - [WithMarshalers] affects marshaling only // - [WithUnmarshalers] affects unmarshaling only @@ -83,6 +82,7 @@ func JoinOptions(srcs ...Options) Options { // GetOption returns the value stored in opts with the provided setter, // reporting whether the value is present. +// If not present, the returned value is the zero value for type T. // // Example usage: // @@ -97,18 +97,33 @@ func GetOption[T any](opts Options, setter func(T) Options) (T, bool) { } // DefaultOptionsV2 is the full set of all options that define v2 semantics. -// It is equivalent to all options under [Options], [encoding/json.Options], -// and [encoding/json/jsontext.Options] being set to false or the zero value, -// except for the options related to whitespace formatting. +// It is equivalent to the set of options in [encoding/json.DefaultOptionsV1] +// all being set to false. All other options are not present. func DefaultOptionsV2() Options { return &jsonopts.DefaultOptionsV2 } -// StringifyNumbers specifies that numeric Go types should be marshaled -// as a JSON string containing the equivalent JSON number value. -// When unmarshaling, numeric Go types are parsed from a JSON string +// StringifyNumbers specifies that types that would normally be +// encoded as a JSON number instead be encoded as a JSON string +// containing the equivalent JSON number value. +// When unmarshaling, the value is parsed from a JSON string // containing the JSON number without any surrounding whitespace. // +// Specifying the `string` tag option on a Go struct field applies this option +// to the top-level JSON value for that field. When applied via the `string` +// tag option, StringifyNumbers option does not recursively apply to nested +// JSON numbers within a JSON object or array. +// +// Like all options, explicitly specifying this option in a call to [Marshal], +// [Unmarshal], etc, will apply recursively. +// +// A Go type with custom marshal/unmarshal that represents a JSON number +// should respect the StringifyNumbers option and if specified +// serialize as a JSON number within a JSON string. +// Custom marshal/unmarshal should handle nested JSON objects using +// [MarshalEncode]/[UnmarshalDecode], which will automatically apply the +// non-recursive `string` tag option behavior. +// // According to RFC 8259, section 6, a JSON implementation may choose to // limit the representation of a JSON number to an IEEE 754 binary64 value. // This may cause decoders to lose precision for int64 and uint64 types. @@ -123,11 +138,18 @@ func StringifyNumbers(v bool) Options { } } -// Deterministic specifies that the same input value will be serialized -// as the exact same output bytes. Different processes of -// the same program will serialize equal values to the same bytes, -// but different versions of the same program are not guaranteed -// to produce the exact same sequence of bytes. +// Deterministic specifies that marshaling the same input value will always +// serialize as the same output bytes. +// +// For example, Go maps are marshaled sorted by key. +// +// For native Go types, Determinism is guaranteed across different instances of +// identical binaries, but not across different builds of a program (such as +// different source or toolchain version, different GOOS/GOARCH, different +// build flags). +// +// A Go type with a custom marshaler should also respect the Deterministic +// option and serialize deterministically if it is true. // // This only affects marshaling and is ignored when unmarshaling. func Deterministic(v bool) Options { @@ -141,8 +163,6 @@ func Deterministic(v bool) Options { // FormatNilSliceAsNull specifies that a nil Go slice should marshal as a // JSON null instead of the default representation as an empty JSON array // (or an empty JSON string in the case of ~[]byte). -// Slice fields explicitly marked with `format:emitempty` still marshal -// as an empty JSON array. // // This only affects marshaling and is ignored when unmarshaling. func FormatNilSliceAsNull(v bool) Options { @@ -155,8 +175,6 @@ func FormatNilSliceAsNull(v bool) Options { // FormatNilMapAsNull specifies that a nil Go map should marshal as a // JSON null instead of the default representation as an empty JSON object. -// Map fields explicitly marked with `format:emitempty` still marshal -// as an empty JSON object. // // This only affects marshaling and is ignored when unmarshaling. func FormatNilMapAsNull(v bool) Options { @@ -167,11 +185,11 @@ func FormatNilMapAsNull(v bool) Options { } } -// OmitZeroStructFields specifies that a Go struct should marshal in such a way -// that all struct fields that are zero are omitted from the marshaled output -// if the value is zero as determined by the "IsZero() bool" method if present, -// otherwise based on whether the field is the zero Go value. -// This is semantically equivalent to specifying the `omitzero` tag option +// OmitZeroStructFields specifies that zero-valued fields of Go struct should be +// omitted from the marshaled output. +// A value is considered zero if its type has an "IsZero() bool" method that returns true, +// or if it lacks such a method and the value is a Go zero value. +// This option is equivalent to specifying the `omitzero` tag option // on every field in a Go struct. // // This only affects marshaling and is ignored when unmarshaling. @@ -185,14 +203,25 @@ func OmitZeroStructFields(v bool) Options { // MatchCaseInsensitiveNames specifies that JSON object members are matched // against Go struct fields using a case-insensitive match of the name. +// If a name matches multiple fields, the field whose name matches exactly is chosen. +// If there is none, an error is reported. // Go struct fields explicitly marked with `case:strict` or `case:ignore` // always use case-sensitive (or case-insensitive) name matching, // regardless of the value of this option. // // This affects either marshaling or unmarshaling. -// For marshaling, this option may alter the detection of duplicate names -// (assuming [jsontext.AllowDuplicateNames] is false) from inlined fields -// if it matches one of the declared fields in the Go struct. +// +// Matching names case-insensitively also affects duplicate name detection +// (assuming [jsontext.AllowDuplicateNames] is false) since +// variations of the same name may match the same Go struct field. +// For example, when unmarshaling, the names "foo" and "Foo" may both +// match the same Go struct field and therefore be considered a duplicate name. +// When marshaling, normally it is impossible for any two Go struct fields to +// serialize in a way where they unmarshal into the same Go struct field +// since they all have unique exact names. +// However, it is possible for an +// embedded fallback to contain a name that also matches the name for +// a Go struct field, resulting in a duplicate name error. func MatchCaseInsensitiveNames(v bool) Options { if v { return jsonflags.MatchCaseInsensitiveNames | 1 @@ -201,22 +230,8 @@ func MatchCaseInsensitiveNames(v bool) Options { } } -// DiscardUnknownMembers specifies that marshaling should ignore any -// JSON object members stored in Go struct fields dedicated to storing -// unknown JSON object members. -// -// This only affects marshaling and is ignored when unmarshaling. -func DiscardUnknownMembers(v bool) Options { - if v { - return jsonflags.DiscardUnknownMembers | 1 - } else { - return jsonflags.DiscardUnknownMembers | 0 - } -} - // RejectUnknownMembers specifies that unknown members should be rejected -// when unmarshaling a JSON object, regardless of whether there is a field -// to store unknown members. +// when unmarshaling a JSON object. // // This only affects unmarshaling and is ignored when marshaling. func RejectUnknownMembers(v bool) Options { diff --git a/vendor/github.com/go-json-experiment/json/options_format.go b/vendor/github.com/go-json-experiment/json/options_format.go new file mode 100644 index 0000000..9f4e975 --- /dev/null +++ b/vendor/github.com/go-json-experiment/json/options_format.go @@ -0,0 +1,122 @@ +// Copyright 2026 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 + +// NOTE: While [ExperimentalSupportFormatTag] is exported, +// it is in an internal package and thus inaccessible for public use. +// +// The [github.com/go-json-experiment/json] module is kept in sync +// with the Go standard standard library and will expose this option +// in a way that public code can now directly reference. + +type supportFormatTag struct { + Options + v bool +} + +var ( + enableFormatTag = supportFormatTag{v: true} + disableFormatTag = supportFormatTag{v: false} +) + +// ExperimentalSupportFormatTag is a marker method that is specially +// recognized by the "encoding/json/v2" runtime. +func (o *supportFormatTag) ExperimentalSupportFormatTag() bool { + return o.v +} + +// ExperimentalSupportFormatTag enables support for the `format` tag. +// +// WARNING: This is an experimental feature and will be removed in the future +// as either a failed experiment or be formally included in "encoding/json/v2" +// in some semantically similar form, in which case, users of this option +// must migrate to the officially supported feature. +// +// The `format` tag was originally part of the "encoding/json/v2" experiment +// but support for it was removed (see https://go.dev/issue/79071) for the +// initial release of "encoding/json/v2" in light of the anticipation that +// the Go language might support typed struct tags (https://go.dev/issue/74472). +// +// Typed struct tags are a more expressive and type-safe way to express format +// attributes than the bespoke `format` tag option that implements a miniature +// domain-specific language (DSL) within the "json" package itself. +// +// While "encoding/json/v2" was in the experimental phase, +// some users were already depending on the `format` tag option. +// This experimental option exists to provide a temporary workaround +// until the (hopeful) inclusion of typed struct tags and support for +// formatting directives in "encoding/json/v2" using that language mechanism. +// +// This option enables support for the `format` tag option, which specifies +// a format flag used to specialize the formatting of the field value. +// The option is a key-value pair specified as "format:value" where +// the value must be either a literal consisting of letters and numbers +// (e.g., `format:RFC3339`) or a single-quoted string literal +// (e.g., `format:'2006-01-02'`). The interpretation of the format flag +// is determined by the struct field type. +// +// Go types with alternative representations are as follows: +// +// - A Go []byte or [N]byte is usually represented as a JSON string +// containing the binary value encoded using RFC 4648. +// If the format is "base64" or unspecified, then this uses RFC 4648, section 4. +// If the format is "base64url", then this uses RFC 4648, section 5. +// If the format is "base32", then this uses RFC 4648, section 6. +// If the format is "base32hex", then this uses RFC 4648, section 7. +// If the format is "base16" or "hex", then this uses RFC 4648, section 8. +// If the format is "array", then the bytes value is represented as a JSON array +// where each element recursively uses the JSON representation of each byte. +// +// - A Go float is usually represented as a JSON number. +// If the format is "nonfinite", then NaN, +Inf, and -Inf are represented as +// the JSON strings "NaN", "Infinity", and "-Infinity", respectively. +// Without the use of this format, such string values result in a [SemanticError]. +// +// - A nil Go map is usually encoded using an empty JSON object. +// If the format is "emitnull", then a nil map is encoded as a JSON null. +// If the format is "emitempty", then a nil map is encoded as an empty JSON object, +// regardless of whether [FormatNilMapAsNull] is specified. +// +// - A nil Go slice is usually encoded using an empty JSON array. +// If the format is "emitnull", then a nil slice is encoded as a JSON null. +// If the format is "emitempty", then a nil slice is encoded as an empty JSON array, +// regardless of whether [FormatNilSliceAsNull] is specified. +// +// - A Go pointer usually uses the JSON representation of the underlying value. +// The format is forwarded to the marshaling and unmarshaling of the underlying type. +// +// - A Go [time.Time] is usually represented as a JSON string containing +// the timestamp formatted in RFC 3339 with nanosecond precision. +// If the format matches one of the format constants declared +// in the time package (e.g., RFC1123), then that format is used. +// If the format is "unix", "unixmilli", "unixmicro", or "unixnano", +// then the timestamp is represented as a possibly fractional JSON number +// of the number of seconds (or milliseconds, microseconds, or nanoseconds) +// since the Unix epoch, which is January 1st, 1970 at 00:00:00 UTC. +// To avoid a fractional component when encoding, +// round the timestamp to the relevant unit. +// Otherwise if non-empty, the format is used as-is and +// encoded using [time.Time.Format] and +// decoded using [time.Time.Parse]. +// +// - A Go [time.Duration] usually has no default representation. +// If the format is "sec", "milli", "micro", or "nano", +// then the duration is represented as a possibly fractional JSON number +// of the number of seconds (or milliseconds, microseconds, or nanoseconds). +// To avoid a fractional component when encoding, +// round the duration to the relevant unit. +// If the format is "units", it is represented as a JSON string +// encoded using [time.Duration.String] and decoded using [time.ParseDuration] +// (e.g., "1h30m" for 1 hour 30 minutes). +// If the format is "iso8601", it is represented as a JSON string using the +// ISO 8601 standard for durations (e.g., "PT1H30M" for 1 hour 30 minutes) +// using only accurate units of hours, minutes, and seconds. +func ExperimentalSupportFormatTag(v bool) Options { + if v { + return &enableFormatTag + } else { + return &disableFormatTag + } +} diff --git a/vendor/github.com/go-json-experiment/json/options_format_global.go b/vendor/github.com/go-json-experiment/json/options_format_global.go new file mode 100644 index 0000000..3a60613 --- /dev/null +++ b/vendor/github.com/go-json-experiment/json/options_format_global.go @@ -0,0 +1,30 @@ +// Copyright 2026 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 + +import "sync/atomic" + +var globalEnableFormatTag atomic.Bool + +// ExperimentalGlobalSupportFormatTag globally enables +// [ExperimentalSupportFormatTag] for all calls to +// [Marshal], [MarshalWrite], [MarshalEncode], +// [Unmarshal], [UnmarshalRead], or [UnmarshalDecode]. +// +// WARNING: This is an experimental feature and will be removed in the future +// as either a failed experiment or be formally included in "github.com/go-json-experiment/json" +// in some semantically similar form, in which case, users of this option +// must migrate to the officially supported feature. +func ExperimentalGlobalSupportFormatTag(v bool) { + globalEnableFormatTag.Store(v) +} + +func mayAppendSupportFormatTag(opts []Options) []Options { + if globalEnableFormatTag.Load() { + var optsArr [4]Options + opts = append(append(optsArr[:0], opts...), &enableFormatTag) + } + return opts +} diff --git a/vendor/github.com/go-json-experiment/json/v1/alias.go b/vendor/github.com/go-json-experiment/json/v1/alias.go new file mode 100644 index 0000000..1ad4d30 --- /dev/null +++ b/vendor/github.com/go-json-experiment/json/v1/alias.go @@ -0,0 +1,875 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by alias_gen.go; DO NOT EDIT. + +//go:build goexperiment.jsonv2 && go1.25 + +// Package json 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. +// +// See [JSON and Go] for an introduction to this package. +// +// # Security Considerations +// +// See the "Security Considerations" section in [encoding/json/v2]. +// +// For historical reasons, the default behavior of v1 [encoding/json] +// unfortunately operates with less secure defaults. +// New usages of JSON in Go are encouraged to use [encoding/json/v2] instead. +// +// [JSON and Go]: https://go.dev/blog/json +// Migrating to v2 +// +// This package (i.e., [encoding/json]) is now formally known as the v1 package +// since a v2 package now exists at [encoding/json/v2]. +// All the behavior of the v1 package is implemented in terms of +// the v2 package with the appropriate set of options specified that +// preserve the historical behavior of v1. +// +// The [jsonv2.Marshal] function is the newer equivalent of v1 [Marshal]. +// The [jsonv2.Unmarshal] function is the newer equivalent of v1 [Unmarshal]. +// The v2 functions have the same calling signature as the v1 equivalent +// except that they take in variadic [Options] arguments that can be specified +// to alter the behavior of marshal or unmarshal. Both v1 and v2 generally +// behave in similar ways, but there are some notable differences. +// +// The following is a list of differences between v1 and v2: +// +// - In v1, JSON object members are unmarshaled into a Go struct using a +// case-insensitive name match with the JSON name of the fields. +// In contrast, v2 matches fields using an exact, case-sensitive match. +// The [jsonv2.MatchCaseInsensitiveNames] and [MatchCaseSensitiveDelimiter] +// options control this behavior difference. To explicitly specify a Go struct +// field to use a particular name matching scheme, either the `case:ignore` +// or the `case:strict` field option can be specified. +// Field-specified options take precedence over caller-specified options. +// +// - In v1, when marshaling a Go struct, a field marked as `omitempty` +// is omitted if the field value is an "empty" Go value, which is defined as +// false, 0, a nil pointer, a nil interface value, and +// any empty array, slice, map, or string. In contrast, v2 redefines +// `omitempty` to omit a field if it encodes as an "empty" JSON value, +// which is defined as a JSON null, or an empty JSON string, object, or array. +// The [OmitEmptyWithLegacySemantics] option controls this behavior difference. +// Note that `omitempty` behaves identically in both v1 and v2 for a +// Go array, slice, map, or string (assuming no user-defined MarshalJSON method +// overrides the default representation). Existing usages of `omitempty` on a +// Go bool, number, pointer, or interface value should migrate to specifying +// `omitzero` instead (which is identically supported in both v1 and v2). +// +// - In v1, a Go struct field marked as `string` can be used to quote a +// Go string, bool, number, or pointer to such as a JSON string. +// In contrast, v2 restricts the `string` option to only quote a value +// that would normally be represented as a JSON number, +// but also expands support for it to operate with any Go type +// that would normally be represented as a JSON number. +// The [StringifyWithLegacySemantics] option controls this behavior difference. +// +// - In v1, a nil Go slice or Go map is marshaled as a JSON null. +// In contrast, v2 marshals a nil Go slice or Go map as +// an empty JSON array or JSON object, respectively. +// The [jsonv2.FormatNilSliceAsNull] and [jsonv2.FormatNilMapAsNull] options +// control this behavior difference. +// +// - In v1, a Go array may be unmarshaled from a JSON array of any length. +// In contrast, in v2 a Go array must be unmarshaled from a JSON array +// of the same length, otherwise it results in an error. +// The [UnmarshalArrayFromAnyLength] option controls this behavior difference. +// +// - In v1, a Go byte array is represented as a JSON array of JSON numbers. +// In contrast, in v2 a Go byte array is represented as a Base64-encoded JSON string. +// The [FormatByteArrayAsArray] option controls this behavior difference. +// +// - In v1, MarshalJSON methods declared on a pointer receiver are only called +// if the Go value is addressable. In contrast, in v2 a MarshalJSON method +// is always callable regardless of addressability. +// The [CallMethodsWithLegacySemantics] option controls this behavior difference. +// +// - In v1, MarshalJSON and UnmarshalJSON methods are never called for Go map keys. +// In contrast, in v2 a MarshalJSON or UnmarshalJSON method is eligible for +// being called for Go map keys. +// The [CallMethodsWithLegacySemantics] option controls this behavior difference. +// +// - In v1, a Go map is marshaled in a deterministic order. +// In contrast, in v2 a Go map is marshaled in a non-deterministic order. +// The [jsonv2.Deterministic] option controls this behavior difference. +// +// - In v1, JSON strings are encoded with HTML-specific or JavaScript-specific +// characters being escaped. In contrast, in v2 JSON strings use the minimal +// encoding and only escape if required by the JSON grammar. +// The [jsontext.EscapeForHTML] and [jsontext.EscapeForJS] options +// control this behavior difference. +// +// - In v1, bytes of invalid UTF-8 within a string are silently replaced with +// the Unicode replacement character. In contrast, in v2 the presence of +// invalid UTF-8 results in an error. The [jsontext.AllowInvalidUTF8] option +// controls this behavior difference. +// +// - In v1, a JSON object with duplicate names is permitted. +// In contrast, in v2 a JSON object with duplicate names results in an error. +// The [jsontext.AllowDuplicateNames] option controls this behavior difference. +// +// - In v1, when unmarshaling a JSON null into a non-empty Go value it will +// inconsistently either zero out the value or do nothing. +// In contrast, in v2 unmarshaling a JSON null will consistently and always +// zero out the underlying Go value. The [MergeWithLegacySemantics] option +// controls this behavior difference. +// +// - In v1, when unmarshaling a JSON value into a non-zero Go value, +// it merges into the original Go value for array elements, slice elements, +// struct fields (but not map values), +// pointer values, and interface values (only if a non-nil pointer). +// In contrast, in v2 unmarshal merges into the Go value +// for struct fields, map values, pointer values, and interface values. +// In general, the v2 semantic merges when unmarshaling a JSON object, +// otherwise it replaces the value. The [MergeWithLegacySemantics] option +// controls this behavior difference. +// +// - In v1, a [time.Duration] is represented as a JSON number containing +// the decimal number of nanoseconds. In contrast, in v2 a [time.Duration] +// has no default representation and results in a runtime error. +// The [FormatDurationAsNano] option controls this behavior difference. +// +// - In v1, errors are never reported at runtime for Go struct types +// that have some form of structural error (e.g., a malformed tag option). +// In contrast, v2 reports a runtime error for Go types that are invalid +// as they relate to JSON serialization. For example, a Go struct +// with only unexported fields cannot be serialized. +// The [ReportErrorsWithLegacySemantics] option controls this behavior difference. +// +// As mentioned, the entirety of v1 is implemented in terms of v2, +// where options are implicitly specified to opt into legacy behavior. +// For example, [Marshal] directly calls [jsonv2.Marshal] with [DefaultOptionsV1]. +// Similarly, [Unmarshal] directly calls [jsonv2.Unmarshal] with [DefaultOptionsV1]. +// The [DefaultOptionsV1] option represents the set of all options that specify +// default v1 behavior. +// +// For many of the behavior differences, there are Go struct field options +// that the author of a Go type can specify to control the behavior such that +// the type is represented identically in JSON under either v1 or v2 semantics. +// +// The availability of [DefaultOptionsV1] and [jsonv2.DefaultOptionsV2], +// where later options take precedence over former options allows for +// a gradual migration from v1 to v2. For example: +// +// - jsonv1.Marshal(v) +// uses default v1 semantics. +// +// - jsonv2.Marshal(v, jsonv1.DefaultOptionsV1()) +// is semantically equivalent to jsonv1.Marshal +// and thus uses default v1 semantics. +// +// - jsonv2.Marshal(v, jsonv1.DefaultOptionsV1(), jsontext.AllowDuplicateNames(false)) +// uses mostly v1 semantics, but opts into one particular v2-specific behavior. +// +// - jsonv2.Marshal(v, jsonv1.CallMethodsWithLegacySemantics(true)) +// uses mostly v2 semantics, but opts into one particular v1-specific behavior. +// +// - jsonv2.Marshal(v, ..., jsonv2.DefaultOptionsV2()) +// is semantically equivalent to jsonv2.Marshal since +// jsonv2.DefaultOptionsV2 overrides any options specified earlier +// and thus uses default v2 semantics. +// +// - jsonv2.Marshal(v) +// uses default v2 semantics. +// +// All new usages of "json" in Go should use the v2 package, +// but the v1 package will forever remain supported. +// +// See the [encoding/json/v2 Migration Guide] for additional detail on migration approaches. +// +// [encoding/json/v2 Migration Guide]: https://go.dev/doc/jsonv2-migration +package json + +import ( + "bytes" + "encoding/json" + "io" +) + +// Unmarshal parses the JSON-encoded data and stores the result +// in the value pointed to by v. If v is nil or not a pointer, +// Unmarshal returns an [InvalidUnmarshalError]. +// +// 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. +// +// The JSON input is decoded according the following rules: +// +// - If the value type implements [jsonv2.UnmarshalerFrom], +// then the UnmarshalJSONFrom method is called to decode the JSON value. +// If the method returns [errors.ErrUnsupported], +// then the input is decoded according to subsequent rules. +// +// - If the value type implements [Unmarshaler], +// then the UnmarshalJSON method is called to decode the JSON value, +// including when the input is a JSON null. +// +// - If the value implements [encoding.TextUnmarshaler] and +// the input is a JSON string, then the UnmarshalText method +// is called with the unquoted form of the string. +// +// Otherwise, Unmarshal uses the following type-dependent default decodings: +// +// 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. By +// default, object keys which don't have a corresponding struct field are +// ignored (see [Decoder.DisallowUnknownFields] for an alternative). +// +// 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 +// - []any, for JSON arrays +// - map[string]any, for JSON objects +// - nil for JSON null +// +// To unmarshal a JSON array into a slice, Unmarshal decodes each JSON array +// element into the corresponding slice element, reusing existing slice +// elements in-place. The slice grows to accommodate additional elements, +// or is truncated if the JSON array is shorter. +// 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 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. The map's key type must +// either be any string type, an integer, or implement [encoding.TextUnmarshaler]. +// +// If the JSON-encoded data contain a syntax error, Unmarshal returns a [SyntaxError]. +// +// 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. +// +// 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 any) error { + return json.Unmarshal(data, v) +} + +// Unmarshaler is the interface implemented by types +// 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 = json.Unmarshaler + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError = json.UnmarshalTypeError + +// An UnmarshalFieldError describes a JSON object key that +// led to an unexported (and therefore unwritable) struct field. +// +// Deprecated: No longer used; kept for compatibility. +type UnmarshalFieldError = json.UnmarshalFieldError + +// An InvalidUnmarshalError describes an invalid argument passed to [Unmarshal]. +// (The argument to [Unmarshal] must be a non-nil pointer.) +type InvalidUnmarshalError = json.InvalidUnmarshalError + +// A Number represents a JSON number literal. +type Number = json.Number + +// Marshal returns the JSON encoding of v. +// +// Marshal traverses the value v recursively. +// +// The input value is encoded as JSON according the following rules: +// +// - If the value type implements [jsonv2.MarshalerTo], +// then the MarshalJSONTo method is called to encode the value. +// If the method returns [errors.ErrUnsupported], +// then the input is encoded according to subsequent rules. +// +// - If the value type implements [Marshaler], +// then the MarshalJSON method is called to encode the value. +// +// - If the value type implements [encoding.TextAppender], +// then the AppendText method is called to encode the value and +// subsequently encode its result as a JSON string. +// +// - If the value type implements [encoding.TextMarshaler], +// then the MarshalText method is called to encode the value and +// subsequently encode its result as a JSON string. +// +// 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. +// NaN and +/-Inf values will return an [UnsupportedValueError]. +// +// String values encode as JSON strings coerced to valid UTF-8, +// replacing invalid bytes with the Unicode replacement rune. +// So that the JSON will be safe to embed inside HTML - + +